http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-update-manager/src/main/resources/META-INF/spring/update-manager-context.xml
----------------------------------------------------------------------
diff --git 
a/taverna-workbench-update-manager/src/main/resources/META-INF/spring/update-manager-context.xml
 
b/taverna-workbench-update-manager/src/main/resources/META-INF/spring/update-manager-context.xml
new file mode 100644
index 0000000..c3adf1f
--- /dev/null
+++ 
b/taverna-workbench-update-manager/src/main/resources/META-INF/spring/update-manager-context.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      
http://www.springframework.org/schema/beans/spring-beans.xsd";>
+
+       <bean id="UpdateMenuAction"
+               
class="net.sf.taverna.t2.workbench.update.impl.menu.UpdateMenuAction">
+               <property name="updateManager" ref="updateManager" />
+       </bean>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-workbench-impl/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-workbench-impl/pom.xml 
b/taverna-workbench-workbench-impl/pom.xml
new file mode 100644
index 0000000..5b52d3a
--- /dev/null
+++ b/taverna-workbench-workbench-impl/pom.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+       <modelVersion>4.0.0</modelVersion>
+       <parent>
+               <groupId>net.sf.taverna.t2</groupId>
+               <artifactId>ui-impl</artifactId>
+               <version>2.0-SNAPSHOT</version>
+       </parent>
+       <groupId>net.sf.taverna.t2.ui-impl</groupId>
+       <artifactId>workbench-impl</artifactId>
+       <packaging>bundle</packaging>
+       <name>Workbench UI implementation</name>
+       <description>The main workbench ui</description>
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.felix</groupId>
+                               <artifactId>maven-bundle-plugin</artifactId>
+                               <configuration>
+                                       <instructions>
+                                               
<Embed-Dependency>osxapplication</Embed-Dependency>
+                                               
<Import-Package>com.apple.eawt;resolution:=optional,*</Import-Package>
+                                       </instructions>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+       <dependencies>
+               <dependency>
+                       <groupId>net.sf.taverna.t2.ui-api</groupId>
+                       <artifactId>workbench-api</artifactId>
+                       <version>${t2.ui.api.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>net.sf.taverna.t2.ui-api</groupId>
+                       <artifactId>edits-api</artifactId>
+                       <version>${t2.ui.api.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>net.sf.taverna.t2.ui-api</groupId>
+                       <artifactId>configuration-api</artifactId>
+                       <version>${t2.ui.api.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>net.sf.taverna.t2.ui-api</groupId>
+                       <artifactId>file-api</artifactId>
+                       <version>${t2.ui.api.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>net.sf.taverna.t2.ui-api</groupId>
+                       <artifactId>helper-api</artifactId>
+                       <version>${t2.ui.api.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>net.sf.taverna.t2.ui-api</groupId>
+                       <artifactId>menu-api</artifactId>
+                       <version>${t2.ui.api.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>net.sf.taverna.t2.ui-api</groupId>
+                       <artifactId>selection-api</artifactId>
+                       <version>${t2.ui.api.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>net.sf.taverna.t2.lang</groupId>
+                       <artifactId>observer</artifactId>
+                       <version>${t2.lang.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>net.sf.taverna.t2.lang</groupId>
+                       <artifactId>ui</artifactId>
+                       <version>${t2.lang.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>uk.org.taverna.commons</groupId>
+                       <artifactId>taverna-plugin-api</artifactId>
+                       <version>${taverna.commons.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>uk.org.taverna.configuration</groupId>
+                       <artifactId>taverna-configuration-api</artifactId>
+                       <version>${taverna.configuration.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>uk.org.taverna.configuration</groupId>
+                       <artifactId>taverna-app-configuration-api</artifactId>
+                       <version>${taverna.configuration.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>uk.org.taverna.scufl2</groupId>
+                       <artifactId>scufl2-api</artifactId>
+                       <version>${scufl2.version}</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>commons-io</groupId>
+                       <artifactId>commons-io</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>log4j</groupId>
+                       <artifactId>log4j</artifactId>
+               </dependency>
+
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.simplericity.macify</groupId>
+                       <artifactId>macify</artifactId>
+                       <version>1.6</version>
+               </dependency>
+       </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/DataflowEditsListener.java
----------------------------------------------------------------------
diff --git 
a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/DataflowEditsListener.java
 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/DataflowEditsListener.java
new file mode 100644
index 0000000..4c493d1
--- /dev/null
+++ 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/DataflowEditsListener.java
@@ -0,0 +1,93 @@
+package net.sf.taverna.t2.workbench.ui.impl;
+
+import static 
uk.org.taverna.scufl2.api.container.WorkflowBundle.generateIdentifier;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.taverna.t2.lang.observer.Observable;
+import net.sf.taverna.t2.lang.observer.Observer;
+import net.sf.taverna.t2.workbench.edits.Edit;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.edits.EditManager.AbstractDataflowEditEvent;
+import net.sf.taverna.t2.workbench.edits.EditManager.DataFlowRedoEvent;
+import net.sf.taverna.t2.workbench.edits.EditManager.DataFlowUndoEvent;
+import net.sf.taverna.t2.workbench.edits.EditManager.DataflowEditEvent;
+import net.sf.taverna.t2.workbench.edits.EditManager.EditManagerEvent;
+import net.sf.taverna.t2.workflow.edits.UpdateDataflowInternalIdentifierEdit;
+
+import org.apache.log4j.Logger;
+
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+
+/**
+ * Listens out for any edits on a dataflow and changes its internal id (or back
+ * to the old one in the case of redo/undo). Is first created when the 
workbench
+ * is initialised.
+ * 
+ * @author Ian Dunlop
+ */
+public class DataflowEditsListener implements Observer<EditManagerEvent> {
+       private static Logger logger = Logger
+                       .getLogger(DataflowEditsListener.class);
+
+       private Map<Edit<?>, URI> dataflowEditMap;
+
+       public DataflowEditsListener() {
+               super();
+               dataflowEditMap = new HashMap<>();
+       }
+
+       /**
+        * Receives {@link EditManagerEvent}s from the {@link EditManager} and
+        * changes the id of the {@link Dataflow} to a new one or back to its 
old
+        * one depending on whether it is a do/undo/redo event. Stores the 
actual
+        * edit and the pre-edit dataflow id in a Map and changes the id when it
+        * gets further actions against this same edit
+        */
+       @Override
+       public void notify(Observable<EditManagerEvent> observable,
+                       EditManagerEvent event) throws Exception {
+               Edit<?> edit = event.getEdit();
+               WorkflowBundle dataFlow = ((AbstractDataflowEditEvent) event)
+                               .getDataFlow();
+
+               if (event instanceof DataflowEditEvent) {
+                       /*
+                        * the dataflow has been edited in some way so change 
its internal
+                        * id and store the old one against the edit that is 
changing
+                        * 'something'
+                        */
+                       URI internalIdentifier = dataFlow.getGlobalBaseURI();
+                       dataflowEditMap.put(edit, internalIdentifier);
+                       URI newIdentifier = generateIdentifier();
+                       new UpdateDataflowInternalIdentifierEdit(dataFlow, 
newIdentifier)
+                                       .doEdit();
+                       logger.debug("Workflow edit, id changed from: "
+                                       + internalIdentifier + " to " + 
newIdentifier);
+               } else if (event instanceof DataFlowRedoEvent) {
+                       /*
+                        * change the id back to the old one and store the new 
one in case
+                        * we want to change it back
+                        */
+                       URI newId = dataFlow.getGlobalBaseURI();
+                       URI oldId = dataflowEditMap.get(edit);
+                       dataflowEditMap.put(edit, newId);
+                       new UpdateDataflowInternalIdentifierEdit(dataFlow, 
oldId).doEdit();
+                       logger.debug("Workflow edit, id changed from: " + newId 
+ " to "
+                                       + oldId);
+               } else if (event instanceof DataFlowUndoEvent) {
+                       /*
+                        * change the id back to the old one and store the new 
one in case
+                        * we want to change it back
+                        */
+                       URI newId = dataFlow.getGlobalBaseURI();
+                       URI oldId = dataflowEditMap.get(edit);
+                       dataflowEditMap.put(edit, newId);
+                       new UpdateDataflowInternalIdentifierEdit(dataFlow, 
oldId).doEdit();
+                       logger.debug("Workflow edit, id changed from: " + newId 
+ " to "
+                                       + oldId);
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/LoggerStream.java
----------------------------------------------------------------------
diff --git 
a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/LoggerStream.java
 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/LoggerStream.java
new file mode 100644
index 0000000..fe13d4d
--- /dev/null
+++ 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/LoggerStream.java
@@ -0,0 +1,136 @@
+/***************************************
+ *                                     *
+ *  JBoss: The OpenSource J2EE WebOS   *
+ *                                     *
+ *  Distributable under LGPL license.  *
+ *  See terms of license at gnu.org.   *
+ *                                     *
+ *  Modified by Stian Soiland-Reyes    *
+ *                                     *
+ ***************************************/
+package net.sf.taverna.t2.workbench.ui.impl;
+
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.Level;
+
+/**
+ * A subclass of PrintStream that redirects its output to a log4j Logger.
+ *
+ * <p>This class is used to map PrintStream/PrintWriter oriented logging onto
+ *    the log4j Categories. Examples include capturing System.out/System.err
+ *
+ * @version <tt>$Revision: 1.1.1.1 $</tt>
+ * @author <a href="mailto:scott.st...@jboss.org";>Scott Stark</a>.
+ * @author <a href="mailto:ja...@planet57.com";>Jason Dillon</a>
+ */
+//FIXME Replace this class entirely
+class LoggerStream extends PrintStream {
+       /**
+        * Default flag to enable/disable tracing println calls. from the system
+        * property 
<tt>net.sf.taverna.t2.workbench.ui.impl.LoggerStream.trace</tt>
+        * or if not set defaults to <tt>false</tt>.
+        */
+   public static final boolean TRACE =
+                  getBoolean(LoggerStream.class.getName() + ".trace", false);
+
+       /**
+        * Helper to get boolean value from system property or use default if 
not
+        * set.
+        */
+       private static boolean getBoolean(String name, boolean defaultValue) {
+               String value = System.getProperty(name, null);
+               if (value == null)
+                       return defaultValue;
+               return new Boolean(value).booleanValue();
+       }
+
+       private Logger logger;
+       private Level level;
+       private boolean issuedWarning;
+
+       /**
+        * Redirect logging to the indicated logger using Level.INFO
+        */
+       public LoggerStream(Logger logger) {
+               this(logger, Level.INFO, System.out);
+       }
+
+       /**
+        * Redirect logging to the indicated logger using the given level. The 
ps is
+        * simply passed to super but is not used.
+        */
+       public LoggerStream(Logger logger, Level level, PrintStream ps) {
+               super(ps);
+               this.logger = logger;
+               this.level = level;
+       }
+
+       @Override
+       public void println(String msg) {
+               if (msg == null)
+                       msg = "null";
+               byte[] bytes = msg.getBytes();
+               write(bytes, 0, bytes.length);
+       }
+
+       @Override
+       public void println(Object msg) {
+               if (msg == null)
+                       msg = "null";
+               byte[] bytes = msg.toString().getBytes();
+               write(bytes, 0, bytes.length);
+       }
+
+       public void write(byte b) {
+               byte[] bytes = { b };
+               write(bytes, 0, 1);
+       }
+
+       private ThreadLocal<Boolean> recursiveCheck = new ThreadLocal<>();
+
+       @Override
+       public void write(byte[] b, int off, int len) {
+               Boolean recursed = recursiveCheck.get();
+               if (recursed != null && recursed) {
+                       /*
+                        * There is a configuration error that is causing 
looping. Most
+                        * likely there are two console appenders so just 
return to prevent
+                        * spinning.
+                        */
+                       if (issuedWarning == false) {
+                               String msg = "ERROR: invalid log settings 
detected, console capturing is looping";
+                               // out.write(msg.getBytes());
+                               new 
Exception(msg).printStackTrace((PrintStream) out);
+                               issuedWarning = true;
+                       }
+                       try {
+                               out.write(b, off, len);
+                       } catch (IOException e) {
+                       }
+                       return;
+               }
+
+               // Remove the end of line chars
+               while (len > 0 && (b[len - 1] == '\n' || b[len - 1] == '\r')
+                               && len > off)
+                       len--;
+
+               /*
+                * HACK, something is logging exceptions line by line (including
+                * blanks), but I can't seem to find it, so for now just ignore 
empty
+                * lines... they aren't very useful.
+                */
+               if (len != 0) {
+                       String msg = new String(b, off, len);
+                       recursiveCheck.set(true);
+                       if (TRACE)
+                               logger.log(level, msg, new Throwable());
+                       else
+                               logger.log(level, msg);
+                       recursiveCheck.set(false);
+               }
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/SetConsoleLoggerStartup.java
----------------------------------------------------------------------
diff --git 
a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/SetConsoleLoggerStartup.java
 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/SetConsoleLoggerStartup.java
new file mode 100644
index 0000000..a8bdfdd
--- /dev/null
+++ 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/SetConsoleLoggerStartup.java
@@ -0,0 +1,62 @@
+package net.sf.taverna.t2.workbench.ui.impl;
+
+import static org.apache.log4j.Level.ERROR;
+import static org.apache.log4j.Level.WARN;
+
+import java.io.PrintStream;
+
+import net.sf.taverna.t2.workbench.StartupSPI;
+import 
net.sf.taverna.t2.workbench.configuration.workbench.WorkbenchConfiguration;
+
+import org.apache.log4j.ConsoleAppender;
+import org.apache.log4j.Logger;
+
+public class SetConsoleLoggerStartup implements StartupSPI {
+       private static final PrintStream originalErr = System.err;
+       private static final PrintStream originalOut = System.out;
+
+       private final WorkbenchConfiguration workbenchConfiguration;
+
+       public SetConsoleLoggerStartup(WorkbenchConfiguration 
workbenchConfiguration) {
+               this.workbenchConfiguration = workbenchConfiguration;
+       }
+
+       @Override
+       public int positionHint() {
+               /*
+                * Must be <b>after</b> PrepareLoggerStarup in file-translator 
--
+                * otherwise Taverna 1 libraries will cause double logging
+                */
+               return 10;
+       }
+
+       @Override
+       public boolean startup() {
+               setSystemOutCapture();
+               return true;
+       }
+
+       public void setSystemOutCapture() {
+               if (!workbenchConfiguration.getCaptureConsole()) {
+                       System.setOut(originalOut);
+                       System.setErr(originalErr);
+                       return;
+               }
+               Logger systemOutLogger = Logger.getLogger("System.out");
+               Logger systemErrLogger = Logger.getLogger("System.err");
+
+               try {
+                       /*
+                        * This logger stream not loop with log4j > 1.2.13, 
which has
+                        * getFollow method
+                        */
+                       ConsoleAppender.class.getMethod("getFollow");
+                       System.setOut(new LoggerStream(systemOutLogger, WARN, 
originalOut));
+               } catch (SecurityException e) {
+               } catch (NoSuchMethodException e) {
+                       System.err.println("Not capturing System.out, use log4j 
>= 1.2.13");
+               }
+
+               System.setErr(new LoggerStream(systemErrLogger, ERROR, 
originalErr));
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/StoreWindowStateOnShutdown.java
----------------------------------------------------------------------
diff --git 
a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/StoreWindowStateOnShutdown.java
 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/StoreWindowStateOnShutdown.java
new file mode 100644
index 0000000..2537f0b
--- /dev/null
+++ 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/StoreWindowStateOnShutdown.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (C) 2008-2010 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 net.sf.taverna.t2.workbench.ui.impl;
+
+import org.apache.log4j.Logger;
+
+import net.sf.taverna.t2.workbench.ShutdownSPI;
+import net.sf.taverna.t2.workbench.ui.Workbench;
+
+/**
+ * Store Workbench window size and perspectives, so that settings can be used 
on
+ * next startup.
+ * 
+ * @author Stian Soiland-Reyes
+ */
+public class StoreWindowStateOnShutdown implements ShutdownSPI {
+       private static Logger logger = Logger
+                       .getLogger(StoreWindowStateOnShutdown.class);
+
+       private Workbench workbench;
+
+       @Override
+       public int positionHint() {
+               return 1000;
+       }
+
+       @Override
+       public boolean shutdown() {
+               try {
+                       workbench.storeSizeAndLocationPrefs();
+               } catch (Exception ex) {
+                       logger.error("Error saving the Workbench size and 
position", ex);
+               }
+               return true;
+       }
+
+       public void setWorkbench(Workbench workbench) {
+               this.workbench = workbench;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/UserRegistrationData.java
----------------------------------------------------------------------
diff --git 
a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/UserRegistrationData.java
 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/UserRegistrationData.java
new file mode 100644
index 0000000..3e32f7b
--- /dev/null
+++ 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/UserRegistrationData.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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 net.sf.taverna.t2.workbench.ui.impl;
+
+public class UserRegistrationData {
+       private String tavernaVersion = "";
+       private String firstName = "";
+       private String lastName = "";
+       private String emailAddress = "";
+       private String institutionOrCompanyName = "";
+       private String industry = "";
+       private String field = "";
+       private String purposeOfUsingTaverna = "";
+       private boolean keepMeInformed = false;
+
+       public void setTavernaVersion(String tavernaVersion) {
+               this.tavernaVersion = tavernaVersion;
+       }
+
+       public String getTavernaVersion() {
+               return tavernaVersion;
+       }
+
+       public void setFirstName(String firstName) {
+               this.firstName = firstName;
+       }
+
+       public String getFirstName() {
+               return firstName;
+       }
+
+       public void setLastName(String lastName) {
+               this.lastName = lastName;
+       }
+
+       public String getLastName() {
+               return lastName;
+       }
+
+       public void setEmailAddress(String emailAddress) {
+               this.emailAddress = emailAddress;
+       }
+
+       public String getEmailAddress() {
+               return emailAddress;
+       }
+
+       public void setInstitutionOrCompanyName(String 
institutionOrCompanyName) {
+               this.institutionOrCompanyName = institutionOrCompanyName;
+       }
+
+       public String getInstitutionOrCompanyName() {
+               return institutionOrCompanyName;
+       }
+
+       public void setIndustry(String industry) {
+               this.industry = industry;
+       }
+
+       public String getIndustry() {
+               return industry;
+       }
+
+       public void setField(String field) {
+               this.field = field;
+       }
+
+       public String getField() {
+               return field;
+       }
+
+       public void setPurposeOfUsingTaverna(String purposeOfUsingTaverna) {
+               this.purposeOfUsingTaverna = purposeOfUsingTaverna;
+       }
+
+       public String getPurposeOfUsingTaverna() {
+               return purposeOfUsingTaverna;
+       }
+
+       public void setKeepMeInformed(boolean keepMeInformed) {
+               this.keepMeInformed = keepMeInformed;
+       }
+
+       public boolean getKeepMeInformed() {
+               return keepMeInformed;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/UserRegistrationForm.java
----------------------------------------------------------------------
diff --git 
a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/UserRegistrationForm.java
 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/UserRegistrationForm.java
new file mode 100644
index 0000000..97f831f
--- /dev/null
+++ 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/UserRegistrationForm.java
@@ -0,0 +1,995 @@
+/*******************************************************************************
+ * 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 net.sf.taverna.t2.workbench.ui.impl;
+
+import static java.awt.BorderLayout.CENTER;
+import static java.awt.BorderLayout.NORTH;
+import static java.awt.Color.LIGHT_GRAY;
+import static java.awt.Color.WHITE;
+import static java.awt.FlowLayout.LEFT;
+import static java.awt.Font.BOLD;
+import static java.awt.GridBagConstraints.FIRST_LINE_START;
+import static java.awt.GridBagConstraints.HORIZONTAL;
+import static java.awt.GridBagConstraints.LINE_START;
+import static java.awt.GridBagConstraints.NONE;
+import static java.awt.GridBagConstraints.WEST;
+import static java.awt.event.KeyEvent.VK_ENTER;
+import static java.awt.event.KeyEvent.VK_TAB;
+import static javax.swing.JOptionPane.ERROR_MESSAGE;
+import static javax.swing.JOptionPane.showMessageDialog;
+import static javax.swing.SwingConstants.BOTTOM;
+import static javax.swing.SwingConstants.TOP;
+import static javax.swing.event.HyperlinkEvent.EventType.ACTIVATED;
+import static 
net.sf.taverna.t2.workbench.icons.WorkbenchIcons.tavernaCogs32x32Icon;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Desktop;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.ConnectException;
+import java.net.MalformedURLException;
+import java.net.SocketTimeoutException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.Properties;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JEditorPane;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.border.Border;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+import javax.swing.text.Document;
+import javax.swing.text.html.HTMLEditorKit;
+import javax.swing.text.html.StyleSheet;
+
+import net.sf.taverna.t2.lang.ui.DialogTextArea;
+import net.sf.taverna.t2.workbench.helper.HelpEnabledDialog;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.log4j.Logger;
+/**
+ * User registration form.
+ * 
+ * @author Alex Nenadic
+ */
+@SuppressWarnings("serial")
+public class UserRegistrationForm extends HelpEnabledDialog {
+       private static final String FAILED = "User registration failed: ";
+
+       private static final String REGISTRATION_FAILED_MSG = "User 
registration failed. Please try again later.";
+
+       private static final String REGISTRATION_URL = 
"http://www.mygrid.org.uk/taverna/registration/";;
+
+       public static final String TAVERNA_VERSION_PROPERTY_NAME = "Taverna 
version";
+       public static final String FIRST_NAME_PROPERTY_NAME = "First name";
+       public static final String LAST_NAME_PROPERTY_NAME = "Last name";
+       public static final String EMAIL_ADDRESS_PROPERTY_NAME = "Email 
address";
+       public static final String INSTITUTION_OR_COMPANY_PROPERTY_NAME = 
"Institution or company name";
+       public static final String INDUSTRY_PROPERTY_NAME = "Industry";
+       public static final String FIELD_PROPERTY_NAME = "Field of 
investigation";
+       public static final String PURPOSE_PROPERTY_NAME = "Purpose of using 
Taverna";
+       public static final String KEEP_ME_INFORMED_PROPERTY_NAME = "Keep me 
informed by email";
+
+       public static final String TAVERNA_REGISTRATION_POST_PARAMETER_NAME = 
"taverna_registration";
+       public static final String TAVERNA_VERSION_POST_PARAMETER_NAME = 
"taverna_version";
+       public static final String FIRST_NAME_POST_PARAMETER_NAME = 
"first_name";
+       public static final String LAST_NAME_POST_PARAMETER_NAME = "last_name";
+       public static final String EMAIL_ADDRESS_POST_PARAMETER_NAME = "email";
+       public static final String INSTITUTION_OR_COMPANY_POST_PARAMETER_NAME = 
"institution_or_company";
+       public static final String INDUSTRY_TYPE_POST_PARAMETER_NAME = 
"industry_type";
+       public static final String FIELD_POST_PARAMETER_NAME = "field";
+       public static final String PURPOSE_POST_PARAMETER_NAME = "purpose";
+       public static final String 
KEEP_ME_INFORMED_POST_PARAMETER_PROPERTY_NAME = "keep_me_informed";
+
+       private static String TRUE = Boolean.TRUE.toString();
+       private static String FALSE = Boolean.FALSE.toString();
+
+       private static final String WELCOME = "Welcome to the Taverna User 
Registration Form";
+       private static final String PLEASE_FILL_IN_THIS_REGISTRATION_FORM = 
"Please fill in this registration form to let us know that you are using 
Taverna";
+
+       private static final String WE_DO = "Note that by registering:\n"
+                       + "   \u25CF We do not have access to your data\n"
+                       + "   \u25CF We do not have access to your service 
usage\n"
+                       + "   \u25CF You will not be monitored\n"
+                       + "   \u25CF We do record the information you provide\n"
+                       + "     at registration time";
+
+       private static final String WHY_REGISTER = "By registering you will:\n"
+                       + "   \u25CF Allow us to support you better; future 
plans will be\n"
+                       + "     directed towards solutions Taverna users 
require\n"
+                       + "   \u25CF Help sustain Taverna development; our 
continued\n"
+                       + "     funding relies on us showing usage\n"
+                       + "   \u25CF (Optionally) Hear about news and product 
updates";
+
+       private static final String FIRST_NAME = "*First name:";
+       private static final String LAST_NAME = "*Last name:";
+       private static final String EMAIL_ADDRESS = "*Email address:";
+       private static final String KEEP_ME_INFORMED = "Keep me informed of 
news and product updates via email";
+       private static final String INSTITUTION_COMPANY_NAME = 
"*Institution/Company name:";
+       private static final String FIELD_OF_INVESTIGATION = " Field of 
investigation:\n"
+                       + " (e.g. bioinformatics)";
+       private static final String WHY_YOU_INTEND_TO_USE_TAVERNA = " A brief 
description of how you intend\n"
+                       + " to use Taverna: (e.g. genome analysis\n"
+                       + " for bacterial strain identification)";
+
+       private static String[] industryTypes = { "", "Academia - Life 
Sciences",
+                       "Academia - Social Sciences", "Academia - Physical 
Sciences",
+                       "Academia - Environmental Sciences", "Academia - Other",
+                       "Industry - Biotechnology", "Industry - Pharmaceutical",
+                       "Industry - Engineering", "Industry - Other",
+                       "Healthcare Services", "Goverment and Public Sector", 
"Other" };
+
+       private static final String I_AGREE_TO_THE_TERMS_AND_CONDITIONS = "I 
agree to the terms and conditions of registration at";
+       private static final String TERMS_AND_CONDITIONS_URL = 
"http://www.taverna.org.uk/legal/terms";;
+
+       private Logger logger = Logger.getLogger(UserRegistrationForm.class);
+       private UserRegistrationData previousRegistrationData;
+       private JTextField firstNameTextField;
+       private JTextField lastNameTextField;
+       private JTextField emailTextField;
+       private JCheckBox keepMeInformedCheckBox;
+       private JTextField institutionOrCompanyTextField;
+       private JComboBox<String> industryTypeTextField;
+       private JTextField fieldTextField;
+       private JTextArea purposeTextArea;
+       private JCheckBox termsAndConditionsCheckBox;
+
+       private final File registrationDataFile;
+       private final File remindMeLaterFile;
+       private final File doNotRegisterMeFile;
+       private final String appName;
+
+       public UserRegistrationForm(String appName, File registrationDataFile,
+                       File doNotRegisterMeFile, File remindMeLaterFile) {
+               super((Frame) null, "Taverna User Registration", true);
+               this.appName = appName;
+               this.registrationDataFile = registrationDataFile;
+               this.doNotRegisterMeFile = doNotRegisterMeFile;
+               this.remindMeLaterFile = remindMeLaterFile;
+               initComponents();
+       }
+
+       public UserRegistrationForm(String appName,
+                       File previousRegistrationDataFile, File 
registrationDataFile,
+                       File doNotRegisterMeFile, File remindMeLaterFile) {
+               super((Frame) null, "Taverna User Registration", true);
+               this.appName = appName;
+               this.registrationDataFile = registrationDataFile;
+               this.doNotRegisterMeFile = doNotRegisterMeFile;
+               this.remindMeLaterFile = remindMeLaterFile;
+               previousRegistrationData = 
loadUserRegistrationData(previousRegistrationDataFile);
+               initComponents();
+       }
+
+       // For testing only
+       // public static void main(String[] args) throws ClassNotFoundException,
+       // InstantiationException, IllegalAccessException,
+       // UnsupportedLookAndFeelException{
+       // WorkbenchImpl.setLookAndFeel();
+       // UserRegistrationForm form = new UserRegistrationForm();
+       // form.setVisible(true);
+       // }
+
+       private void initComponents() {
+               JPanel mainPanel = new JPanel(new GridBagLayout());
+
+               // Base font for all components on the form
+               Font baseFont = new JLabel("base 
font").getFont().deriveFont(11f);
+
+               // Title panel
+               JPanel titlePanel = new JPanel(new FlowLayout(LEFT));
+               titlePanel.setBackground(WHITE);
+               // titlePanel.setBorder(new EmptyBorder(10, 10, 10, 10));
+               JLabel titleLabel = new JLabel(WELCOME);
+               titleLabel.setFont(baseFont.deriveFont(BOLD, 13.5f));
+               // titleLabel.setBorder(new EmptyBorder(10, 10, 0, 10));
+               JLabel titleIcon = new JLabel(tavernaCogs32x32Icon);
+               // titleIcon.setBorder(new EmptyBorder(10, 10, 10, 10));
+               DialogTextArea titleMessage = new DialogTextArea(
+                               PLEASE_FILL_IN_THIS_REGISTRATION_FORM);
+               titleMessage.setMargin(new Insets(0, 20, 0, 10));
+               titleMessage.setFont(baseFont);
+               titleMessage.setEditable(false);
+               titleMessage.setFocusable(false);
+               // titlePanel.setBorder( new EmptyBorder(10, 10, 0, 10));
+               JPanel messagePanel = new JPanel(new BorderLayout());
+               messagePanel.add(titleLabel, NORTH);
+               messagePanel.add(titleMessage, CENTER);
+               messagePanel.setBackground(WHITE);
+               titlePanel.add(titleIcon);
+               titlePanel.add(messagePanel);
+               addDivider(titlePanel, BOTTOM, true);
+
+               GridBagConstraints gbc = new GridBagConstraints();
+               gbc.weightx = 1.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 0;
+               gbc.gridy = 0;
+               gbc.fill = HORIZONTAL;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 2;
+               // gbc.insets = new Insets(5, 10, 0, 0);
+               mainPanel.add(titlePanel, gbc);
+
+               // Registration messages
+               gbc.weightx = 0.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 0;
+               gbc.gridy = 1;
+               gbc.fill = NONE;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 2;
+               // gbc.insets = new Insets(5, 0, 0, 10);
+               DialogTextArea registrationMessage1 = new 
DialogTextArea(WHY_REGISTER);
+               registrationMessage1.setMargin(new Insets(0, 10, 0, 0));
+               registrationMessage1.setFont(baseFont);
+               registrationMessage1.setEditable(false);
+               registrationMessage1.setFocusable(false);
+               registrationMessage1.setBackground(getBackground());
+
+               DialogTextArea registrationMessage2 = new DialogTextArea(WE_DO);
+               registrationMessage2.setMargin(new Insets(0, 10, 0, 10));
+               registrationMessage2.setFont(baseFont);
+               registrationMessage2.setEditable(false);
+               registrationMessage2.setFocusable(false);
+               registrationMessage2.setBackground(getBackground());
+               JPanel registrationMessagePanel = new JPanel(new FlowLayout(
+                               FlowLayout.CENTER));
+               registrationMessagePanel.add(registrationMessage1);
+               registrationMessagePanel.add(registrationMessage2);
+               addDivider(registrationMessagePanel, BOTTOM, true);
+               mainPanel.add(registrationMessagePanel, gbc);
+
+               // Mandatory label
+               // JLabel mandatoryLabel = new JLabel("* Mandatory fields");
+               // mandatoryLabel.setFont(baseFont);
+               // gbc.weightx = 0.0;
+               // gbc.weighty = 0.0;
+               // gbc.gridx = 0;
+               // gbc.gridy = 3;
+               // gbc.fill = NONE;
+               // gbc.anchor = GridBagConstraints.EAST;
+               // gbc.gridwidth = 2;
+               // gbc.insets = new Insets(0, 10, 0, 20);
+               // mainPanel.add(mandatoryLabel, gbc);
+
+               // First name
+               JLabel firstNameLabel = new JLabel(FIRST_NAME);
+               firstNameLabel.setFont(baseFont);
+               gbc.weightx = 0.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 0;
+               gbc.gridy = 4;
+               gbc.fill = NONE;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(0, 10, 0, 10);
+               mainPanel.add(firstNameLabel, gbc);
+
+               firstNameTextField = new JTextField();
+               firstNameTextField.setFont(baseFont);
+               if (previousRegistrationData != null)
+                       
firstNameTextField.setText(previousRegistrationData.getFirstName());
+               gbc.weightx = 1.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 1;
+               gbc.gridy = 4;
+               gbc.fill = HORIZONTAL;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               mainPanel.add(firstNameTextField, gbc);
+
+               // Last name
+               JLabel lastNameLabel = new JLabel(LAST_NAME);
+               lastNameLabel.setFont(baseFont);
+               gbc.weightx = 0.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 0;
+               gbc.gridy = 5;
+               gbc.fill = NONE;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(0, 10, 0, 10);
+               mainPanel.add(lastNameLabel, gbc);
+
+               lastNameTextField = new JTextField();
+               lastNameTextField.setFont(baseFont);
+               if (previousRegistrationData != null)
+                       
lastNameTextField.setText(previousRegistrationData.getLastName());
+               gbc.weightx = 1.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 1;
+               gbc.gridy = 5;
+               gbc.fill = HORIZONTAL;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               mainPanel.add(lastNameTextField, gbc);
+
+               // Email address
+               JLabel emailLabel = new JLabel(EMAIL_ADDRESS);
+               emailLabel.setFont(baseFont);
+               gbc.weightx = 0.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 0;
+               gbc.gridy = 6;
+               gbc.fill = NONE;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               mainPanel.add(emailLabel, gbc);
+
+               emailTextField = new JTextField();
+               emailTextField.setFont(baseFont);
+               if (previousRegistrationData != null)
+                       
emailTextField.setText(previousRegistrationData.getEmailAddress());
+               gbc.weightx = 1.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 1;
+               gbc.gridy = 6;
+               gbc.fill = HORIZONTAL;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               mainPanel.add(emailTextField, gbc);
+
+               // Keep me informed
+               keepMeInformedCheckBox = new JCheckBox(KEEP_ME_INFORMED);
+               keepMeInformedCheckBox.setFont(baseFont);
+               if (previousRegistrationData != null)
+                       
keepMeInformedCheckBox.setSelected(previousRegistrationData
+                                       .getKeepMeInformed());
+               keepMeInformedCheckBox.addKeyListener(new KeyAdapter() {
+                       @Override
+                       public void keyPressed(KeyEvent evt) {
+                               if (evt.getKeyCode() == VK_ENTER) {
+                                       evt.consume();
+                                       
keepMeInformedCheckBox.setSelected(!keepMeInformedCheckBox
+                                                       .isSelected());
+                               }
+                       }
+               });
+               gbc.weightx = 0.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 1;
+               gbc.gridy = 7;
+               gbc.fill = NONE;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 2;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               mainPanel.add(keepMeInformedCheckBox, gbc);
+
+               // Institution name
+               JLabel institutionLabel = new JLabel(INSTITUTION_COMPANY_NAME);
+               institutionLabel.setFont(baseFont);
+               gbc.weightx = 0.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 0;
+               gbc.gridy = 8;
+               gbc.fill = NONE;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               mainPanel.add(institutionLabel, gbc);
+
+               institutionOrCompanyTextField = new JTextField();
+               institutionOrCompanyTextField.setFont(baseFont);
+               if (previousRegistrationData != null)
+                       
institutionOrCompanyTextField.setText(previousRegistrationData
+                                       .getInstitutionOrCompanyName());
+               gbc.weightx = 1.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 1;
+               gbc.gridy = 8;
+               gbc.fill = HORIZONTAL;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               mainPanel.add(institutionOrCompanyTextField, gbc);
+
+               // Industry type
+               JLabel industryLabel = new JLabel(" Industry type:");
+               industryLabel.setFont(baseFont);
+               gbc.weightx = 0.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 0;
+               gbc.gridy = 9;
+               gbc.fill = NONE;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               mainPanel.add(industryLabel, gbc);
+
+               industryTypeTextField = new JComboBox<>(industryTypes);
+               industryTypeTextField.setFont(baseFont);
+               if (previousRegistrationData != null)
+                       
industryTypeTextField.setSelectedItem(previousRegistrationData
+                                       .getIndustry());
+               gbc.weightx = 1.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 1;
+               gbc.gridy = 9;
+               gbc.fill = HORIZONTAL;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               mainPanel.add(industryTypeTextField, gbc);
+
+               // Field of investigation
+               JTextArea fieldLabel = new JTextArea(FIELD_OF_INVESTIGATION);
+               fieldLabel.setFont(baseFont);
+               fieldLabel.setEditable(false);
+               fieldLabel.setFocusable(false);
+               fieldLabel.setBackground(getBackground());
+               gbc.weightx = 0.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 0;
+               gbc.gridy = 10;
+               gbc.fill = NONE;
+               gbc.anchor = LINE_START;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               mainPanel.add(fieldLabel, gbc);
+
+               fieldTextField = new JTextField();
+               fieldTextField.setFont(baseFont);
+               if (previousRegistrationData != null)
+                       
fieldTextField.setText(previousRegistrationData.getField());
+               gbc.weightx = 1.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 1;
+               gbc.gridy = 10;
+               gbc.fill = HORIZONTAL;
+               gbc.anchor = FIRST_LINE_START;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               mainPanel.add(fieldTextField, gbc);
+
+               // Purpose of using Taverna
+               JTextArea purposeLabel = new 
JTextArea(WHY_YOU_INTEND_TO_USE_TAVERNA);
+               purposeLabel.setFont(baseFont);
+               purposeLabel.setEditable(false);
+               purposeLabel.setFocusable(false);
+               purposeLabel.setBackground(getBackground());
+               gbc.weightx = 0.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 0;
+               gbc.gridy = 11;
+               gbc.fill = NONE;
+               gbc.anchor = LINE_START;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               mainPanel.add(purposeLabel, gbc);
+
+               purposeTextArea = new JTextArea(4, 30);
+               purposeTextArea.setFont(baseFont);
+               purposeTextArea.setLineWrap(true);
+               purposeTextArea.setAutoscrolls(true);
+               if (previousRegistrationData != null)
+                       purposeTextArea.setText(previousRegistrationData
+                                       .getPurposeOfUsingTaverna());
+               purposeTextArea.addKeyListener(new KeyAdapter() {
+                       @Override
+                       public void keyPressed(KeyEvent evt) {
+                               if (evt.getKeyCode() == VK_TAB) {
+                                       if (evt.getModifiers() > 0)
+                                               
purposeTextArea.transferFocusBackward();
+                                       else
+                                               purposeTextArea.transferFocus();
+                                       evt.consume();
+                               }
+                       }
+               });
+               JScrollPane purposeScrollPane = new 
JScrollPane(purposeTextArea);
+               gbc.weightx = 1.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 1;
+               gbc.gridy = 11;
+               gbc.fill = HORIZONTAL;
+               gbc.anchor = FIRST_LINE_START;
+               gbc.gridwidth = 1;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               mainPanel.add(purposeScrollPane, gbc);
+
+               // Terms and conditions
+               termsAndConditionsCheckBox = new JCheckBox(
+                               I_AGREE_TO_THE_TERMS_AND_CONDITIONS);
+               termsAndConditionsCheckBox.setFont(baseFont);
+               termsAndConditionsCheckBox.setBorder(null);
+               termsAndConditionsCheckBox.addKeyListener(new KeyAdapter() {
+                       @Override
+                       public void keyPressed(KeyEvent evt) {
+                               if (evt.getKeyCode() == VK_ENTER) {
+                                       evt.consume();
+                                       termsAndConditionsCheckBox
+                                                       
.setSelected(!termsAndConditionsCheckBox
+                                                                       
.isSelected());
+                               }
+                       }
+               });
+               // gbc.weightx = 0.0;
+               // gbc.weighty = 0.0;
+               // gbc.gridx = 0;
+               // gbc.gridy = 12;
+               // gbc.fill = NONE;
+               // gbc.anchor = WEST;
+               // gbc.gridwidth = 2;
+               // gbc.insets = new Insets(10, 10, 0, 0);
+               // mainPanel.add(termsAndConditionsCheckBox, gbc);
+
+               // Terms and conditions link
+               JEditorPane termsAndConditionsURL = new JEditorPane();
+               termsAndConditionsURL.setEditable(false);
+               termsAndConditionsURL.setBackground(getBackground());
+               termsAndConditionsURL.setFocusable(false);
+               HTMLEditorKit kit = new HTMLEditorKit();
+               termsAndConditionsURL.setEditorKit(kit);
+               StyleSheet styleSheet = kit.getStyleSheet();
+               // styleSheet.addRule("body 
{font-family:"+baseFont.getFamily()+"; font-size:"+baseFont.getSize()+";}");
+               // // base font looks bigger when rendered as HTML
+               styleSheet.addRule("body {font-family:" + baseFont.getFamily()
+                               + "; font-size:9px;}");
+               Document doc = kit.createDefaultDocument();
+               termsAndConditionsURL.setDocument(doc);
+               termsAndConditionsURL.setText("<html><body><a href=\""
+                               + TERMS_AND_CONDITIONS_URL + "\">" + 
TERMS_AND_CONDITIONS_URL
+                               + "</a></body></html>");
+               termsAndConditionsURL.addHyperlinkListener(new 
HyperlinkListener() {
+                       @Override
+                       public void hyperlinkUpdate(HyperlinkEvent he) {
+                               if (he.getEventType() == ACTIVATED)
+                                       followHyperlinkToTandCs();
+                       }
+               });
+               gbc.weightx = 0.0;
+               gbc.weighty = 0.0;
+               gbc.gridx = 0;
+               gbc.gridy = 13;
+               gbc.fill = NONE;
+               gbc.anchor = WEST;
+               gbc.gridwidth = 2;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               JPanel termsAndConditionsPanel = new JPanel(new 
FlowLayout(LEFT));
+               termsAndConditionsPanel.add(termsAndConditionsCheckBox);
+               termsAndConditionsPanel.add(termsAndConditionsURL);
+               mainPanel.add(termsAndConditionsPanel, gbc);
+
+               // Button panel
+               JPanel buttonPanel = new JPanel(new 
FlowLayout(FlowLayout.CENTER));
+               JButton registerButton = new JButton("Register");
+               registerButton.setFont(baseFont);
+               registerButton.addKeyListener(new KeyAdapter() {
+                       @Override
+                       public void keyPressed(KeyEvent evt) {
+                               if (evt.getKeyCode() == VK_ENTER) {
+                                       evt.consume();
+                                       register();
+                               }
+                       }
+               });
+               registerButton.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               register();
+                       }
+               });
+               JButton doNotRegisterButton = new JButton("Do not ask me 
again");
+               doNotRegisterButton.setFont(baseFont);
+               doNotRegisterButton.addKeyListener(new KeyAdapter() {
+                       @Override
+                       public void keyPressed(KeyEvent evt) {
+                               if (evt.getKeyCode() == VK_ENTER) {
+                                       evt.consume();
+                                       doNotRegister();
+                               }
+                       }
+               });
+               doNotRegisterButton.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               doNotRegister();
+                       }
+               });
+               JButton remindMeLaterButton = new JButton("Remind me later"); 
// in 2 weeks
+               remindMeLaterButton.setFont(baseFont);
+               remindMeLaterButton.addKeyListener(new KeyAdapter() {
+                       @Override
+                       public void keyPressed(KeyEvent evt) {
+                               if (evt.getKeyCode() == VK_ENTER) {
+                                       evt.consume();
+                                       remindMeLater();
+                               }
+                       }
+               });
+               remindMeLaterButton.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               remindMeLater();
+                       }
+               });
+               buttonPanel.add(registerButton);
+               buttonPanel.add(remindMeLaterButton);
+               buttonPanel.add(doNotRegisterButton);
+               addDivider(buttonPanel, TOP, true);
+               gbc.gridx = 0;
+               gbc.gridy = 14;
+               gbc.fill = HORIZONTAL;
+               gbc.anchor = GridBagConstraints.CENTER;
+               gbc.insets = new Insets(5, 10, 0, 10);
+               gbc.gridwidth = 2;
+               mainPanel.add(buttonPanel, gbc);
+
+               getContentPane().setLayout(new BorderLayout());
+               getContentPane().add(mainPanel, CENTER);
+
+               pack();
+               setResizable(false);
+               // Center the dialog on the screen (we do not have the parent)
+               Dimension dimension = getToolkit().getScreenSize();
+               Rectangle abounds = getBounds();
+               setLocation((dimension.width - abounds.width) / 2,
+                               (dimension.height - abounds.height) / 2);
+               setSize(getPreferredSize());
+       }
+
+       protected void remindMeLater() {
+               try {
+                       FileUtils.touch(remindMeLaterFile);
+               } catch (IOException ioex) {
+                       logger.error(
+                                       "Failed to touch the 'Remind me later' 
file at user registration.",
+                                       ioex);
+               }
+               closeDialog();
+       }
+
+       protected void doNotRegister() {
+               try {
+                       FileUtils.touch(doNotRegisterMeFile);
+                       if (remindMeLaterFile.exists())
+                               remindMeLaterFile.delete();
+               } catch (IOException ioex) {
+                       logger.error(
+                                       "Failed to touch the 'Do not register 
me' file at user registration.",
+                                       ioex);
+               }
+               closeDialog();
+       }
+
+       private void register() {
+               if (!validateForm())
+                       return;
+               UserRegistrationData regData = new UserRegistrationData();
+               regData.setTavernaVersion(appName);
+               regData.setFirstName(firstNameTextField.getText());
+               regData.setLastName(lastNameTextField.getText());
+               regData.setEmailAddress(emailTextField.getText());
+               regData.setKeepMeInformed(keepMeInformedCheckBox.isSelected());
+               
regData.setInstitutionOrCompanyName(institutionOrCompanyTextField
+                               .getText());
+               
regData.setIndustry(industryTypeTextField.getSelectedItem().toString());
+               regData.setField(fieldTextField.getText());
+               regData.setPurposeOfUsingTaverna(purposeTextArea.getText());
+
+               if (postUserRegistrationDataToServer(regData)) {
+                       saveUserRegistrationData(regData, registrationDataFile);
+                       if (remindMeLaterFile.exists())
+                               remindMeLaterFile.delete();
+                       closeDialog();
+               }
+       }
+
+       private boolean validateForm() {
+               String errorMessage = "";
+               if (firstNameTextField.getText().isEmpty())
+                       errorMessage += "Please provide your first name.<br>";
+               if (lastNameTextField.getText().isEmpty())
+                       errorMessage += "Please provide your last name.<br>";
+               if (emailTextField.getText().isEmpty())
+                       errorMessage += "Please provide your email 
address.<br>";
+               if (institutionOrCompanyTextField.getText().isEmpty())
+                       errorMessage += "Please provide your institution or 
company name.";
+               if (!errorMessage.isEmpty()) {
+                       showMessageDialog(this, new JLabel("<html><body>"
+                                       + errorMessage + "</body></html>"), 
"Error in form",
+                                       ERROR_MESSAGE);
+                       return false;
+               }
+               if (!termsAndConditionsCheckBox.isSelected()) {
+                       showMessageDialog(this, new JLabel(
+                                       "You must agree to the terms and 
conditions."),
+                                       "Error in form", ERROR_MESSAGE);
+                       return false;
+               }
+               return true;
+       }
+
+       public UserRegistrationData loadUserRegistrationData(File 
propertiesFile) {
+               UserRegistrationData regData = new UserRegistrationData();
+               Properties props = new Properties();
+
+               // Try to retrieve data from file
+               try {
+                       props.load(new FileInputStream(propertiesFile));
+               } catch (IOException e) {
+                       logger.error("Failed to load old user registration data 
from "
+                                       + propertiesFile.getAbsolutePath(), e);
+                       return null;
+               }
+               regData.setTavernaVersion(props
+                               .getProperty(TAVERNA_VERSION_PROPERTY_NAME));
+               
regData.setFirstName(props.getProperty(FIRST_NAME_PROPERTY_NAME));
+               regData.setLastName(props.getProperty(LAST_NAME_PROPERTY_NAME));
+               
regData.setEmailAddress(props.getProperty(EMAIL_ADDRESS_PROPERTY_NAME));
+               regData.setKeepMeInformed(props.getProperty(
+                               KEEP_ME_INFORMED_PROPERTY_NAME).equals(TRUE));
+               regData.setInstitutionOrCompanyName(props
+                               
.getProperty(INSTITUTION_OR_COMPANY_PROPERTY_NAME));
+               regData.setIndustry(props.getProperty(INDUSTRY_PROPERTY_NAME));
+               regData.setField(props.getProperty(FIELD_PROPERTY_NAME));
+               regData.setPurposeOfUsingTaverna(props
+                               .getProperty(PURPOSE_PROPERTY_NAME));
+               return regData;
+       }
+
+       private void enc(StringBuilder buffer, String name, Object value)
+                       throws UnsupportedEncodingException {
+               if (buffer.length() != 0)
+                       buffer.append('&');
+               buffer.append(URLEncoder.encode(name, "UTF-8"));
+               buffer.append('=');
+               buffer.append(URLEncoder.encode(value.toString(), "UTF-8"));
+       }
+
+       /**
+        * Post registration data to our server.
+        */
+       private boolean postUserRegistrationDataToServer(
+                       UserRegistrationData regData) {
+               StringBuilder parameters = new StringBuilder();
+
+               /*
+                * The 'submit' parameter - to let the server-side script know 
we are
+                * submitting the user's registration form - all other requests 
will be
+                * silently ignored
+                */
+               try {
+                       // value does not matter
+                       enc(parameters, 
TAVERNA_REGISTRATION_POST_PARAMETER_NAME, "submit");
+
+                       enc(parameters, TAVERNA_VERSION_POST_PARAMETER_NAME,
+                                       regData.getTavernaVersion());
+                       enc(parameters, FIRST_NAME_POST_PARAMETER_NAME,
+                                       regData.getFirstName());
+                       enc(parameters, LAST_NAME_POST_PARAMETER_NAME,
+                                       regData.getLastName());
+                       enc(parameters, EMAIL_ADDRESS_POST_PARAMETER_NAME,
+                                       regData.getEmailAddress());
+                       enc(parameters, 
KEEP_ME_INFORMED_POST_PARAMETER_PROPERTY_NAME,
+                                       regData.getKeepMeInformed());
+                       enc(parameters, 
INSTITUTION_OR_COMPANY_POST_PARAMETER_NAME,
+                                       regData.getInstitutionOrCompanyName());
+                       enc(parameters, INDUSTRY_TYPE_POST_PARAMETER_NAME,
+                                       regData.getIndustry());
+                       enc(parameters, FIELD_POST_PARAMETER_NAME, 
regData.getField());
+                       enc(parameters, PURPOSE_POST_PARAMETER_NAME,
+                                       regData.getPurposeOfUsingTaverna());
+               } catch (UnsupportedEncodingException ueex) {
+                       logger.error(FAILED + "Could not url encode post 
parameters", ueex);
+                       showMessageDialog(null, REGISTRATION_FAILED_MSG,
+                                       "Error encoding registration data", 
ERROR_MESSAGE);
+                       return false;
+               }
+               String server = REGISTRATION_URL;
+               logger.info("Posting user registartion to " + server
+                               + " with parameters: " + parameters);
+               String response = "";
+               String failure;
+               try {
+                       URL url = new URL(server);
+                       URLConnection conn = url.openConnection();
+                       /*
+                        * Set timeout to e.g. 7 seconds, otherwise we might 
hang too long
+                        * if server is not responding and it will block Taverna
+                        */
+                       conn.setConnectTimeout(7000);
+                       // Set connection parameters
+                       conn.setDoInput(true);
+                       conn.setDoOutput(true);
+                       conn.setUseCaches(false);
+                       // Make server believe we are HTML form data...
+                       conn.setRequestProperty("Content-Type",
+                                       "application/x-www-form-urlencoded");
+                       // Write out the bytes of the content string to the 
stream.
+                       try (DataOutputStream out = new DataOutputStream(
+                                       conn.getOutputStream())) {
+                               out.writeBytes(parameters.toString());
+                               out.flush();
+                       }
+                       // Read response from the input stream.
+                       try (BufferedReader in = new BufferedReader(new 
InputStreamReader(
+                                       conn.getInputStream()))) {
+                               String temp;
+                               while ((temp = in.readLine()) != null)
+                                       response += temp + "\n";
+                               // Remove the last \n character
+                               if (!response.isEmpty())
+                                       response = response.substring(0, 
response.length() - 1);
+                       }
+                       if (response.equals("Registration successful!"))
+                               return true;
+                       logger.error(FAILED + "Response form server was: " + 
response);
+                       failure = "Error saving registration data on the 
server";
+               } catch (ConnectException ceex) {
+                       /*
+                        * the connection was refused remotely (e.g. no process 
is listening
+                        * on the remote address/port).
+                        */
+                       logger.error(
+                                       FAILED
+                                                       + "Registration server 
is not listening of the specified url.",
+                                       ceex);
+                       failure = "Registration server is not listening at the 
specified url";
+               } catch (SocketTimeoutException stex) {
+                       // timeout has occurred on a socket read or accept.
+                       logger.error(FAILED + "Socket timeout occurred.", stex);
+                       failure = "Registration server timeout";
+               } catch (MalformedURLException muex) {
+                       logger.error(FAILED + "Registartion server's url is 
malformed.",
+                                       muex);
+                       failure = "Error with registration server's url";
+               } catch (IOException ioex) {
+                       logger.error(
+                                       FAILED
+                                                       + "Failed to open url 
connection to registration server or writing/reading to/from it.",
+                                       ioex);
+                       failure = "Error opening connection to the registration 
server";
+               }
+               showMessageDialog(null, REGISTRATION_FAILED_MSG, failure, 
ERROR_MESSAGE);
+               return false;
+       }
+
+       private void saveUserRegistrationData(UserRegistrationData regData,
+                       File propertiesFile) {
+               Properties props = new Properties();
+               props.setProperty(TAVERNA_VERSION_PROPERTY_NAME,
+                               regData.getTavernaVersion());
+               props.setProperty(FIRST_NAME_PROPERTY_NAME, 
regData.getFirstName());
+               props.setProperty(LAST_NAME_PROPERTY_NAME, 
regData.getLastName());
+               props.setProperty(EMAIL_ADDRESS_PROPERTY_NAME,
+                               regData.getEmailAddress());
+               props.setProperty(KEEP_ME_INFORMED_PROPERTY_NAME,
+                               regData.getKeepMeInformed() ? TRUE : FALSE);
+               props.setProperty(INSTITUTION_OR_COMPANY_PROPERTY_NAME,
+                               regData.getInstitutionOrCompanyName());
+               props.setProperty(INDUSTRY_PROPERTY_NAME, 
regData.getIndustry());
+               props.setProperty(FIELD_PROPERTY_NAME,
+                               regData.getPurposeOfUsingTaverna());
+               props.setProperty(PURPOSE_PROPERTY_NAME,
+                               regData.getPurposeOfUsingTaverna());
+
+               // Write the properties file.
+               try {
+                       props.store(new FileOutputStream(propertiesFile), null);
+               } catch (Exception e) {
+                       logger.error("Failed to save user registration data 
locally on disk.");
+               }
+       }
+
+       private void closeDialog() {
+               setVisible(false);
+               dispose();
+       }
+
+       /**
+        * Adds a light gray or etched border to the top or bottom of a 
JComponent.
+        * 
+        * @author David Withers
+        * @param component
+        */
+       protected void addDivider(JComponent component, final int position,
+                       final boolean etched) {
+               component.setBorder(new Border() {
+                       private final Color borderColor = new Color(.6f, .6f, 
.6f);
+
+                       @Override
+                       public Insets getBorderInsets(Component c) {
+                               if (position == TOP)
+                                       return new Insets(5, 0, 0, 0);
+                               else
+                                       return new Insets(0, 0, 5, 0);
+                       }
+
+                       @Override
+                       public boolean isBorderOpaque() {
+                               return false;
+                       }
+
+                       @Override
+                       public void paintBorder(Component c, Graphics g, int x, 
int y,
+                                       int width, int height) {
+                               if (position == TOP) {
+                                       if (etched) {
+                                               g.setColor(borderColor);
+                                               g.drawLine(x, y, x + width, y);
+                                               g.setColor(WHITE);
+                                               g.drawLine(x, y + 1, x + width, 
y + 1);
+                                       } else {
+                                               g.setColor(LIGHT_GRAY);
+                                               g.drawLine(x, y, x + width, y);
+                                       }
+                               } else {
+                                       if (etched) {
+                                               g.setColor(borderColor);
+                                               g.drawLine(x, y + height - 2, x 
+ width, y + height - 2);
+                                               g.setColor(WHITE);
+                                               g.drawLine(x, y + height - 1, x 
+ width, y + height - 1);
+                                       } else {
+                                               g.setColor(LIGHT_GRAY);
+                                               g.drawLine(x, y + height - 1, x 
+ width, y + height - 1);
+                                       }
+                               }
+                       }
+               });
+       }
+
+       private void followHyperlinkToTandCs() {
+               // Open a Web browser
+               try {
+                       Desktop.getDesktop().browse(new 
URI(TERMS_AND_CONDITIONS_URL));
+               } catch (Exception ex) {
+                       logger.error("User registration: Failed to launch 
browser to show terms and conditions at "
+                                       + TERMS_AND_CONDITIONS_URL);
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/UserRegistrationHook.java
----------------------------------------------------------------------
diff --git 
a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/UserRegistrationHook.java
 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/UserRegistrationHook.java
new file mode 100644
index 0000000..257c3f3
--- /dev/null
+++ 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/UserRegistrationHook.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (C) 2009-2010 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 net.sf.taverna.t2.workbench.ui.impl;
+
+import static java.awt.GraphicsEnvironment.isHeadless;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.Date;
+
+import net.sf.taverna.t2.workbench.StartupSPI;
+import uk.org.taverna.configuration.app.ApplicationConfiguration;
+
+public class UserRegistrationHook implements StartupSPI {
+       /** Delay between when we ask the user about registration, in 
milliseconds */
+       private static final int TWO_WEEKS = 14 * 24 * 3600 * 1000;
+       public static final String REGISTRATION_DIRECTORY_NAME = "registration";
+       public static final String REGISTRATION_DATA_FILE_NAME = 
"registration_data.properties";
+       public static final String REMIND_ME_LATER_FILE_NAME = 
"remind_me_later";
+       public static final String DO_NOT_REGISTER_ME_FILE_NAME = 
"do_not_register_me";
+
+       private ApplicationConfiguration applicationConfiguration;
+
+       @Override
+       public int positionHint() {
+               return 50;
+       }
+
+       @Override
+       public boolean startup() {
+               File registrationDirectory = getRegistrationDirectory();
+               File registrationDataFile = new File(registrationDirectory,
+                               REGISTRATION_DATA_FILE_NAME);
+               File doNotRegisterMeFile = new File(registrationDirectory,
+                               DO_NOT_REGISTER_ME_FILE_NAME);
+               File remindMeLaterFile = new File(registrationDirectory,
+                               REMIND_ME_LATER_FILE_NAME);
+
+               // if we are running headlessly just return
+               if (isHeadless())
+                       return true;
+               // For Taverna snapshots - do not ask user to register
+               if 
(applicationConfiguration.getName().toLowerCase().contains("snapshot"))
+                       return true;
+
+               // If there is already user's registration data present - exit.
+               if (registrationDataFile.exists())
+                       return true;
+
+               // If user did not want to register - exit.
+               if (doNotRegisterMeFile.exists())
+                       return true;
+
+               /*
+                * If user said to remind them - check if more than 2 weeks 
passed since
+                * we asked previously.
+                */
+               if (remindMeLaterFile.exists()) {
+                       long lastModified = remindMeLaterFile.lastModified();
+                       long now = new Date().getTime();
+                       if (now - lastModified < TWO_WEEKS)
+                               // 2 weeks have not passed since we last asked
+                               return true;
+
+                       // Ask user again if they want to register
+                       UserRegistrationForm form = new UserRegistrationForm(
+                                       applicationConfiguration.getName(), 
registrationDataFile,
+                                       doNotRegisterMeFile, remindMeLaterFile);
+                       form.setVisible(true);
+                       return true;
+               }
+
+               /*
+                * Check if there are previous Taverna versions installed and 
find the
+                * latest one that contains user registration data, if any. Ask 
user if
+                * they want to upload that previous data.
+                */
+               final File appHomeDirectory = 
applicationConfiguration.getApplicationHomeDir();
+               File parentDirectory = appHomeDirectory.getParentFile();
+               FileFilter fileFilter = new FileFilter() {
+                       @Override
+                       public boolean accept(File file) {
+                               return 
!(file.getName().equals(appHomeDirectory.getName())
+                                               // Exclude Taverna home 
directory for this app
+                                               && file.isDirectory()
+                                               && 
file.getName().toLowerCase().startsWith("taverna-")
+                                               // exclude snapshots
+                                               && 
!file.getName().toLowerCase().contains("snapshot")
+                                               // exclude command line tool
+                                               && 
!file.getName().toLowerCase().contains("cmd")
+                                               // exclude dataviewer
+                                               && 
!file.getName().toLowerCase().contains("dataviewer"));
+                       }
+               };
+               File[] tavernaDirectories = 
parentDirectory.listFiles(fileFilter);
+               // Find the latest previous registration data file, if any
+               File previousRegistrationDataFile = null;
+               for (File tavernaDirectory : tavernaDirectories) {
+                       File regFile = new File(tavernaDirectory, 
REGISTRATION_DIRECTORY_NAME
+                                       + System.getProperty("file.separator") 
+ REGISTRATION_DATA_FILE_NAME);
+                       if (!regFile.exists())
+                               continue;
+                       if (previousRegistrationDataFile == null)
+                               previousRegistrationDataFile = regFile;
+                       else if (previousRegistrationDataFile.lastModified() < 
regFile
+                                       .lastModified())
+                               previousRegistrationDataFile = regFile;
+               }
+
+               UserRegistrationForm form;
+               if (previousRegistrationDataFile == null)
+                       // No previous registration file - ask user to register
+                       form = new 
UserRegistrationForm(applicationConfiguration.getName(),
+                                       registrationDataFile, 
doNotRegisterMeFile,
+                                       remindMeLaterFile);
+               else
+                       /*
+                        * Fill in user's old registration data in the form and 
ask them to
+                        * register
+                        */
+                       form = new 
UserRegistrationForm(applicationConfiguration.getName(),
+                                       previousRegistrationDataFile, 
registrationDataFile,
+                                       doNotRegisterMeFile, remindMeLaterFile);
+               form.setVisible(true);
+               return true;
+       }
+
+       /**
+        * Gets the registration directory where info about registration will be
+        * saved to.
+        */
+       public File getRegistrationDirectory() {
+               File home = applicationConfiguration.getApplicationHomeDir();
+
+               File registrationDirectory = new File(home, 
REGISTRATION_DIRECTORY_NAME);
+               if (!registrationDirectory.exists())
+                       registrationDirectory.mkdir();
+               return registrationDirectory;
+       }
+
+       public void setApplicationConfiguration(
+                       ApplicationConfiguration applicationConfiguration) {
+               this.applicationConfiguration = applicationConfiguration;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/WorkbenchImpl.java
----------------------------------------------------------------------
diff --git 
a/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/WorkbenchImpl.java
 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/WorkbenchImpl.java
new file mode 100644
index 0000000..16f189e
--- /dev/null
+++ 
b/taverna-workbench-workbench-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/WorkbenchImpl.java
@@ -0,0 +1,538 @@
+/*******************************************************************************
+ * Copyright (C) 2007-2010 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 net.sf.taverna.t2.workbench.ui.impl;
+
+import static java.awt.GridBagConstraints.BOTH;
+import static java.awt.GridBagConstraints.CENTER;
+import static java.awt.GridBagConstraints.HORIZONTAL;
+import static java.awt.GridBagConstraints.LINE_START;
+import static java.lang.Thread.setDefaultUncaughtExceptionHandler;
+import static java.util.prefs.Preferences.userNodeForPackage;
+import static javax.swing.JOptionPane.ERROR_MESSAGE;
+import static javax.swing.JOptionPane.WARNING_MESSAGE;
+import static javax.swing.JOptionPane.showMessageDialog;
+import static javax.swing.SwingUtilities.invokeLater;
+import static javax.swing.UIManager.getCrossPlatformLookAndFeelClassName;
+import static javax.swing.UIManager.getLookAndFeel;
+import static javax.swing.UIManager.getLookAndFeelDefaults;
+import static javax.swing.UIManager.getSystemLookAndFeelClassName;
+import static net.sf.taverna.t2.workbench.MainWindow.setMainWindow;
+import static 
net.sf.taverna.t2.workbench.icons.WorkbenchIcons.errorMessageIcon;
+import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.infoMessageIcon;
+import static 
net.sf.taverna.t2.workbench.icons.WorkbenchIcons.questionMessageIcon;
+import static 
net.sf.taverna.t2.workbench.icons.WorkbenchIcons.warningMessageIcon;
+import static org.apache.log4j.Logger.getLogger;
+
+import java.awt.CardLayout;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.File;
+import java.io.IOException;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+import java.util.prefs.Preferences;
+
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JMenuBar;
+import javax.swing.JPanel;
+import javax.swing.JToolBar;
+import javax.swing.UIManager;
+
+import net.sf.taverna.t2.lang.observer.Observable;
+import net.sf.taverna.t2.lang.observer.SwingAwareObserver;
+import net.sf.taverna.t2.ui.menu.MenuManager;
+import net.sf.taverna.t2.ui.menu.MenuManager.MenuManagerEvent;
+import net.sf.taverna.t2.ui.menu.MenuManager.UpdatedMenuManagerEvent;
+import net.sf.taverna.t2.workbench.ShutdownSPI;
+import net.sf.taverna.t2.workbench.StartupSPI;
+import 
net.sf.taverna.t2.workbench.configuration.workbench.WorkbenchConfiguration;
+import 
net.sf.taverna.t2.workbench.configuration.workbench.ui.T2ConfigurationFrame;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.file.exceptions.OpenException;
+import net.sf.taverna.t2.workbench.helper.Helper;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import net.sf.taverna.t2.workbench.ui.Workbench;
+import net.sf.taverna.t2.workbench.ui.zaria.PerspectiveSPI;
+
+import org.apache.log4j.Logger;
+import org.simplericity.macify.eawt.Application;
+import org.simplericity.macify.eawt.ApplicationAdapter;
+import org.simplericity.macify.eawt.ApplicationEvent;
+import org.simplericity.macify.eawt.ApplicationListener;
+import org.simplericity.macify.eawt.DefaultApplication;
+
+import uk.org.taverna.commons.plugin.PluginException;
+import uk.org.taverna.commons.plugin.PluginManager;
+import uk.org.taverna.configuration.app.ApplicationConfiguration;
+
+/**
+ * The main workbench frame.
+ *
+ * @author David Withers
+ * @author Stian Soiland-Reyes
+ */
+public class WorkbenchImpl extends JFrame implements Workbench {
+       private static final String NIMBUS = 
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel";
+       private static final String LAUNCHER_LOGO_PNG = "/launcher_logo.png";
+       private static final long serialVersionUID = 1L;
+       private static Logger logger = getLogger(WorkbenchImpl.class);
+       private static Preferences userPreferences = 
userNodeForPackage(WorkbenchImpl.class);
+       
+       private Application osxApp = new DefaultApplication();
+       private ApplicationListener osxAppListener = new OSXAppListener();
+       private MenuManager menuManager;
+       private FileManager fileManager;
+       @SuppressWarnings("unused")
+       private EditManager editManager;
+       private PluginManager pluginManager;
+       private SelectionManager selectionManager;
+       private WorkbenchConfiguration workbenchConfiguration;
+       private ApplicationConfiguration applicationConfiguration;
+       private WorkbenchPerspectives workbenchPerspectives;
+       private T2ConfigurationFrame t2ConfigurationFrame;
+       private JToolBar perspectiveToolBar;
+       private List<StartupSPI> startupHooks;
+       private List<ShutdownSPI> shutdownHooks;
+       private final List<PerspectiveSPI> perspectives;
+       private JMenuBar menuBar;
+       private JToolBar toolBar;
+       private MenuManagerObserver menuManagerObserver;
+
+       public WorkbenchImpl(List<StartupSPI> startupHooks,
+                       List<ShutdownSPI> shutdownHooks, List<PerspectiveSPI> 
perspectives) {
+               this.perspectives = perspectives;
+               this.startupHooks = startupHooks;
+               this.shutdownHooks = shutdownHooks;
+               setMainWindow(this);
+       }
+
+       protected void initialize() {
+               setExceptionHandler();
+               setLookAndFeel();
+
+               // Set icons for Error, Information, Question and Warning 
messages
+               UIManager.put("OptionPane.errorIcon", errorMessageIcon);
+               UIManager.put("OptionPane.informationIcon", infoMessageIcon);
+               UIManager.put("OptionPane.questionIcon", questionMessageIcon);
+               UIManager.put("OptionPane.warningIcon", warningMessageIcon);
+
+               // Call the startup hooks
+               if (!callStartupHooks()) {
+                       System.exit(0);
+               }
+
+               makeGUI();
+               fileManager.newDataflow();
+               try {
+                       pluginManager.loadPlugins();
+               } catch (PluginException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+
+               /*
+                * the DataflowEditsListener changes the WorkflowBundle ID for 
every
+                * workflow edit and changes the URI so port definitions can't 
find the
+                * port they refer to
+                */
+               // TODO check if it's OK to not update the WorkflowBundle ID
+               //editManager.addObserver(new DataflowEditsListener());
+
+               closeTheSplashScreen();
+               setVisible(true);
+       }
+
+       private void closeTheSplashScreen() {
+//             SplashScreen splash = SplashScreen.getSplashScreen();
+//             if (splash != null) {
+//                     splash.setClosable();
+//                     splash.requestClose();
+//             }
+       }
+
+       private void showAboutDialog() {
+               // TODO implement this!
+       }
+
+       private void makeGUI() {
+               setLayout(new GridBagLayout());
+
+               addWindowListener(new WindowClosingListener());
+               setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+
+               Helper.setKeyCatcher(this);
+
+               URL launcherLogo = getClass().getResource(LAUNCHER_LOGO_PNG);
+               if (launcherLogo != null) {
+                       ImageIcon imageIcon = new ImageIcon(launcherLogo);
+                       setIconImage(imageIcon.getImage());
+               }
+               setTitle(applicationConfiguration.getTitle());
+
+               osxApp.setEnabledPreferencesMenu(true);
+               osxApp.setEnabledAboutMenu(true);
+               osxApp.addApplicationListener(osxAppListener);
+
+               /*
+                * Set the size and position of the Workbench to the last saved 
values
+                * or use the default ones the first time it is launched
+                */
+               loadSizeAndLocationPrefs();
+
+               GridBagConstraints gbc = new GridBagConstraints();
+               gbc.gridx = 0;
+               gbc.gridy = 0;
+               gbc.weightx = 0.1;
+               gbc.fill = HORIZONTAL;
+               gbc.anchor = LINE_START;
+
+               add(makeToolbarPanel(), gbc);
+
+               gbc.anchor = CENTER;
+               gbc.fill = BOTH;
+               gbc.gridy = 1;
+               gbc.weightx = 0.1;
+               gbc.weighty = 0.1;
+
+               add(makePerspectivePanel(), gbc);
+
+               menuBar = menuManager.createMenuBar();
+               setJMenuBar(menuBar);
+       }
+
+       protected JPanel makeToolbarPanel() {
+               JPanel toolbarPanel = new JPanel(new GridBagLayout());
+
+               GridBagConstraints gbc = new GridBagConstraints();
+               gbc.gridx = 0;
+               gbc.gridy = 0;
+               gbc.gridwidth = 2;
+               gbc.anchor = LINE_START;
+
+               toolBar = menuManager.createToolBar();
+               toolBar.setFloatable(false);
+               toolbarPanel.add(toolBar, gbc);
+
+               perspectiveToolBar = new JToolBar("Perspectives");
+               perspectiveToolBar.setFloatable(false);
+               gbc.gridy = 1;
+               gbc.weightx = 0.1;
+               gbc.fill = HORIZONTAL;
+               toolbarPanel.add(perspectiveToolBar, gbc);
+
+               return toolbarPanel;
+       }
+
+       private JPanel makePerspectivePanel() {
+               CardLayout perspectiveLayout = new CardLayout();
+               JPanel perspectivePanel = new JPanel(perspectiveLayout);
+               workbenchPerspectives = new 
WorkbenchPerspectives(perspectiveToolBar,
+                               perspectivePanel, perspectiveLayout, 
selectionManager);
+               workbenchPerspectives.setPerspectives(perspectives);
+               return perspectivePanel;
+       }
+
+       @Override
+       public void makeNamedComponentVisible(String componentName) {
+               // basePane.makeNamedComponentVisible(componentName);
+       }
+
+       protected void setExceptionHandler() {
+               setDefaultUncaughtExceptionHandler(new ExceptionHandler());
+       }
+
+       public void setStartupHooks(List<StartupSPI> startupHooks) {
+               this.startupHooks = startupHooks;
+       }
+
+       /**
+        * Calls the startup methods on all the {@link StartupSPI}s. If any 
startup
+        * method returns <code>false</code> (meaning that the Workbench will 
not
+        * function at all) then this method returns <code>false</code>.
+        */
+       private boolean callStartupHooks() {
+               for (StartupSPI startupSPI : startupHooks)
+                       if (!startupSPI.startup())
+                               return false;
+               return true;
+       }
+
+       @Override
+       public void exit() {
+               if (callShutdownHooks())
+                       System.exit(0);
+       }
+
+       public void setShutdownHooks(List<ShutdownSPI> shutdownHooks) {
+               this.shutdownHooks = shutdownHooks;
+       }
+
+       /**
+        * Calls all the shutdown on all the {@link ShutdownSPI}s. If a shutdown
+        * returns <code>false</code> (meaning that the shutdown process should 
be
+        * aborted) then this method returns with a value of <code>false</code>
+        * immediately.
+        *
+        * @return <code>true</code> if all the <code>ShutdownSPIs</code> return
+        *         <code>true</code> and the workbench shutdown should proceed
+        */
+       private boolean callShutdownHooks() {
+               for (ShutdownSPI shutdownSPI : shutdownHooks)
+                       if (!shutdownSPI.shutdown())
+                               return false;
+               return true;
+       }
+
+       /**
+        * Store current Workbench position and size.
+        */
+       @Override
+       public void storeSizeAndLocationPrefs() throws IOException {
+               userPreferences.putInt("width", getWidth());
+               userPreferences.putInt("height", getHeight());
+               userPreferences.putInt("x", getX());
+               userPreferences.putInt("y", getY());
+       }
+
+       /**
+        * Loads last saved Workbench position and size.
+        */
+       private void loadSizeAndLocationPrefs() {
+               Dimension screen = getToolkit().getScreenSize();
+
+               int width = userPreferences.getInt("width", (int) 
(screen.getWidth() * 0.75));
+               int height = userPreferences.getInt("height", (int) 
(screen.getHeight() * 0.75));
+               int x = userPreferences.getInt("x", 0);
+               int y = userPreferences.getInt("y", 0);
+
+               // Make sure our window is not too big
+               width = Math.min((int) screen.getWidth(), width);
+               height = Math.min((int) screen.getHeight(), height);
+
+               // Move to upper left corner if we are too far off
+               if (x > (screen.getWidth() - 50) || x < 0)
+                       x = 0;
+               if (y > (screen.getHeight() - 50) || y < 0)
+                       y = 0;
+
+               this.setSize(width, height);
+               this.setLocation(x, y);
+       }
+
+       public static void setLookAndFeel() {
+               String defaultLaf = System.getProperty("swing.defaultlaf");
+               try {
+                       if (defaultLaf != null) {
+                               UIManager.setLookAndFeel(defaultLaf);
+                               return;
+                       }
+               } catch (Exception e) {
+                       logger.info("Can't set requested look and feel 
-Dswing.defaultlaf="
+                                       + defaultLaf, e);
+               }
+               String os = System.getProperty("os.name");
+               if (os.contains("Mac") || os.contains("Windows")) {
+                       // For OSX and Windows use the system look and feel
+                       String systemLF = getSystemLookAndFeelClassName();
+                       try {
+                               UIManager.setLookAndFeel(systemLF);
+                               getLookAndFeelDefaults().put("ClassLoader",
+                                               
WorkbenchImpl.class.getClassLoader());
+                               logger.info("Using system L&F " + systemLF);
+                               return;
+                       } catch (Exception ex2) {
+                               logger.error("Unable to load system look and 
feel " + systemLF,
+                                               ex2);
+                       }
+               }
+               /*
+                * The system look and feel on *NIX
+                * (com.sun.java.swing.plaf.gtk.GTKLookAndFeel) looks like 
Windows 3.1..
+                * try to use Nimbus (Java 6e10 and later)
+                */
+               try {
+                       UIManager.setLookAndFeel(NIMBUS);
+                       logger.info("Using Nimbus look and feel");
+                       return;
+               } catch (Exception e) {
+               }
+
+               // Metal should be better than GTK still
+               try {
+                       String crossPlatform = 
getCrossPlatformLookAndFeelClassName();
+                       UIManager.setLookAndFeel(crossPlatform);
+                       logger.info("Using cross platform Look and Feel " + 
crossPlatform);
+                       return;
+               } catch (Exception e){
+               }
+
+               // Final fallback
+               try {
+                       String systemLF = getSystemLookAndFeelClassName();
+                       UIManager.setLookAndFeel(systemLF);
+                       logger.info("Using system platform Look and Feel " + 
systemLF);
+               } catch (Exception e){
+                       logger.info("Using default Look and Feel " + 
getLookAndFeel());
+               }
+       }
+
+       public void setMenuManager(MenuManager menuManager) {
+               if (this.menuManager != null && menuManagerObserver != null)
+                       this.menuManager.removeObserver(menuManagerObserver);
+               this.menuManager = menuManager;
+               menuManagerObserver = new MenuManagerObserver();
+               menuManager.addObserver(menuManagerObserver);
+       }
+
+       public void setFileManager(FileManager fileManager) {
+               this.fileManager = fileManager;
+       }
+
+       public void setEditManager(EditManager editManager) {
+               this.editManager = editManager;
+       }
+
+       public void refreshPerspectives(Object service, Map<?,?> properties) {
+               workbenchPerspectives.refreshPerspectives();
+       }
+
+       public void setWorkbenchConfiguration(WorkbenchConfiguration 
workbenchConfiguration) {
+               this.workbenchConfiguration = workbenchConfiguration;
+       }
+
+       public void setApplicationConfiguration(ApplicationConfiguration 
applicationConfiguration) {
+               this.applicationConfiguration = applicationConfiguration;
+       }
+
+       public void setT2ConfigurationFrame(T2ConfigurationFrame 
t2ConfigurationFrame) {
+               this.t2ConfigurationFrame = t2ConfigurationFrame;
+       }
+
+       public void setSelectionManager(SelectionManager selectionManager) {
+               this.selectionManager = selectionManager;
+       }
+
+       public void setPluginManager(PluginManager pluginManager) {
+               this.pluginManager = pluginManager;
+       }
+
+       private final class MenuManagerObserver extends
+                       SwingAwareObserver<MenuManagerEvent> {
+               @Override
+               public void notifySwing(Observable<MenuManagerEvent> sender,
+                               MenuManagerEvent message) {
+                       if (message instanceof UpdatedMenuManagerEvent
+                                       && WorkbenchImpl.this.isVisible())
+                               refreshMenus();
+               }
+       }
+       
+       private void refreshMenus() {
+               if (menuBar != null) {
+                       menuBar.revalidate();
+                       menuBar.repaint();
+               }
+               if (toolBar != null) {
+                       toolBar.revalidate();
+                       toolBar.repaint();
+               }
+       }
+
+       private final class ExceptionHandler implements 
UncaughtExceptionHandler {
+               @Override
+               public void uncaughtException(Thread t, Throwable e) {
+                       logger.error("Uncaught exception in " + t, e);
+                       if (e instanceof Exception
+                                       && 
!workbenchConfiguration.getWarnInternalErrors()) {
+                               /*
+                                * User preference disables warnings - but 
we'll show it anyway
+                                * if it is an Error (which is more serious)
+                                */
+                               return;
+                       }
+                       final String message;
+                       final String title;
+                       final int style;
+                       if 
(t.getClass().getName().equals("java.awt.EventDispatchThread")) {
+                               message = "The user action could not be 
completed due to an unexpected error:\n"
+                                               + e;
+                               title = "Could not complete user action";
+                               style = ERROR_MESSAGE;
+                       } else {
+                               message = "An unexpected internal error occured 
in \n" + t + ":\n" + e;
+                               title = "Unexpected internal error";
+                               style = WARNING_MESSAGE;
+                       }
+                       invokeLater(new Runnable() {
+                               @Override
+                               public void run() {
+                                       showMessageDialog(WorkbenchImpl.this, 
message, title, style);
+                               }
+                       });
+               }
+       }
+
+       private class WindowClosingListener extends WindowAdapter {
+               @Override
+               public void windowClosing(WindowEvent e) {
+                       exit();
+               }
+       }
+
+       private class OSXAppListener extends ApplicationAdapter {
+               @Override
+               public void handleAbout(ApplicationEvent e) {
+                       showAboutDialog();
+                       e.setHandled(true);
+               }
+
+               @Override
+               public void handleQuit(ApplicationEvent e) {
+                       e.setHandled(true);
+                       exit();
+               }
+
+               @Override
+               public void handlePreferences(ApplicationEvent e) {
+                       e.setHandled(true);
+                       t2ConfigurationFrame.showFrame();
+               }
+
+               @Override
+               public void handleOpenFile(ApplicationEvent e) {
+                       try {
+                               if (e.getFilename() != null) {
+                                       fileManager.openDataflow(null, new 
File(e.getFilename()));
+                                       e.setHandled(true);
+                               }
+                       } catch (OpenException | IllegalStateException ex) {
+                               logger.warn("Could not open file " + 
e.getFilename(), ex);
+                       }
+               }
+       }
+}

Reply via email to