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

[06/11] incubator-taverna-workbench git commit:

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenFromURLMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenFromURLMenuAction.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenFromURLMenuAction.java
new file mode 100644
index 0000000..d34767d
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenFromURLMenuAction.java
@@ -0,0 +1,47 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.menu;
+
+import static org.apache.taverna.workbench.file.impl.menu.FileOpenMenuSection.FILE_OPEN_SECTION_URI;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.impl.actions.OpenWorkflowFromURLAction;
+
+public class FileOpenFromURLMenuAction extends AbstractMenuAction {
+
+	private static final URI FILE_OPEN_FROM_URL_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#fileOpenURL");
+	private final FileManager fileManager;
+
+	public FileOpenFromURLMenuAction(FileManager fileManager) {
+		super(FILE_OPEN_SECTION_URI, 30, FILE_OPEN_FROM_URL_URI);
+		this.fileManager = fileManager;
+	}
+
+	@Override
+	protected Action createAction() {
+		return new OpenWorkflowFromURLAction(null, fileManager);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenMenuAction.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenMenuAction.java
new file mode 100644
index 0000000..f7c84cb
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenMenuAction.java
@@ -0,0 +1,46 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+        
+package org.apache.taverna.workbench.file.impl.menu;
+
+import static org.apache.taverna.workbench.file.impl.menu.FileOpenMenuSection.FILE_OPEN_SECTION_URI;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.impl.actions.OpenWorkflowAction;
+
+public class FileOpenMenuAction extends AbstractMenuAction {
+	private static final URI FILE_OPEN_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#fileOpen");
+	private final FileManager fileManager;
+
+	public FileOpenMenuAction(FileManager fileManager) {
+		super(FILE_OPEN_SECTION_URI, 20, FILE_OPEN_URI);
+		this.fileManager = fileManager;
+	}
+
+	@Override
+	protected Action createAction() {
+		return new OpenWorkflowAction(fileManager);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenMenuSection.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenMenuSection.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenMenuSection.java
new file mode 100644
index 0000000..ff8fefd
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenMenuSection.java
@@ -0,0 +1,35 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.menu;
+
+import java.net.URI;
+
+import org.apache.taverna.ui.menu.AbstractMenuSection;
+
+public class FileOpenMenuSection extends AbstractMenuSection {
+	public static final URI FILE_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#file");
+	public static final URI FILE_OPEN_SECTION_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#fileOpenSection");
+
+	public FileOpenMenuSection() {
+		super(FILE_URI, 20, FILE_OPEN_SECTION_URI);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenRecentMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenRecentMenuAction.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenRecentMenuAction.java
new file mode 100644
index 0000000..0a959c3
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileOpenRecentMenuAction.java
@@ -0,0 +1,437 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.menu;
+
+import static java.awt.event.KeyEvent.VK_0;
+import static java.awt.event.KeyEvent.VK_R;
+import static javax.swing.Action.MNEMONIC_KEY;
+import static javax.swing.Action.NAME;
+import static javax.swing.JOptionPane.ERROR_MESSAGE;
+import static javax.swing.JOptionPane.showMessageDialog;
+import static javax.swing.SwingUtilities.invokeLater;
+import static org.apache.taverna.workbench.file.impl.menu.FileOpenMenuSection.FILE_OPEN_SECTION_URI;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+
+import org.apache.taverna.lang.observer.Observable;
+import org.apache.taverna.lang.observer.Observer;
+import org.apache.taverna.ui.menu.AbstractMenuCustom;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.FileType;
+import org.apache.taverna.workbench.file.events.AbstractDataflowEvent;
+import org.apache.taverna.workbench.file.events.ClosedDataflowEvent;
+import org.apache.taverna.workbench.file.events.FileManagerEvent;
+import org.apache.taverna.workbench.file.events.OpenedDataflowEvent;
+import org.apache.taverna.workbench.file.events.SavedDataflowEvent;
+import org.apache.taverna.workbench.file.exceptions.OpenException;
+
+import org.apache.log4j.Logger;
+import org.jdom.Document;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+
+import uk.org.taverna.configuration.app.ApplicationConfiguration;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+
+public class FileOpenRecentMenuAction extends AbstractMenuCustom implements
+		Observer<FileManagerEvent> {
+	public static final URI RECENT_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#fileOpenRecent");
+	private static final String CONF = "conf";
+	private static Logger logger = Logger
+			.getLogger(FileOpenRecentMenuAction.class);
+	private static final String RECENT_WORKFLOWS_XML = "recentWorkflows.xml";
+	private static final int MAX_ITEMS = 10;
+
+	private FileManager fileManager;
+	private ApplicationConfiguration applicationConfiguration;
+	private JMenu menu;
+	private List<Recent> recents = new ArrayList<>();
+	private Thread loadRecentThread;
+
+	public FileOpenRecentMenuAction(FileManager fileManager) {
+		super(FILE_OPEN_SECTION_URI, 30, RECENT_URI);
+		this.fileManager = fileManager;
+		fileManager.addObserver(this);
+	}
+
+	@Override
+	public void notify(Observable<FileManagerEvent> sender,
+			FileManagerEvent message) throws Exception {
+		FileManager fileManager = (FileManager) sender;
+		if (message instanceof OpenedDataflowEvent
+				|| message instanceof SavedDataflowEvent) {
+			AbstractDataflowEvent dataflowEvent = (AbstractDataflowEvent) message;
+			WorkflowBundle dataflow = dataflowEvent.getDataflow();
+			Object dataflowSource = fileManager.getDataflowSource(dataflow);
+			FileType dataflowType = fileManager.getDataflowType(dataflow);
+			addRecent(dataflowSource, dataflowType);
+		}
+		if (message instanceof ClosedDataflowEvent)
+			// Make sure enabled/disabled status is correct
+			updateRecentMenu();
+	}
+
+	public void updateRecentMenu() {
+		invokeLater(new Runnable() {
+			@Override
+			public void run() {
+				updateRecentMenuGUI();
+			}
+		});
+		saveRecent();
+	}
+
+	protected void addRecent(Object dataflowSource, FileType dataflowType) {
+		if (dataflowSource == null)
+			return;
+		if (!(dataflowSource instanceof Serializable)) {
+			logger.warn("Can't serialize workflow source for 'Recent workflows': "
+					+ dataflowSource);
+			return;
+		}
+		synchronized (recents) {
+			Recent recent = new Recent((Serializable) dataflowSource, dataflowType);
+			if (recents.contains(recent))
+				recents.remove(recent);
+			recents.add(0, recent); // Add to front
+		}
+		updateRecentMenu();
+	}
+
+	@Override
+	protected Component createCustomComponent() {
+		action = new DummyAction("Recent workflows");
+		action.putValue(MNEMONIC_KEY, VK_R);
+		menu = new JMenu(action);
+		// Disabled until we have loaded the recent workflows
+		menu.setEnabled(false);
+		loadRecentThread = new Thread("Loading recent workflow menu") {
+			// Avoid hanging GUI initialization while deserialising
+			@Override
+			public void run() {
+				loadRecent();
+				updateRecentMenu();
+			}
+		};
+		loadRecentThread.start();
+		return menu;
+	}
+
+	protected synchronized void loadRecent() {
+		File confDir = new File(applicationConfiguration.getApplicationHomeDir(), CONF);
+		confDir.mkdir();
+		File recentFile = new File(confDir, RECENT_WORKFLOWS_XML);
+		if (!recentFile.isFile())
+			return;
+		try {
+			loadRecent(recentFile);
+		} catch (JDOMException|IOException e) {
+			logger.warn("Could not read recent workflows from file "
+					+ recentFile, e);
+		}
+	}
+
+	private void loadRecent(File recentFile) throws FileNotFoundException,
+			IOException, JDOMException {
+		SAXBuilder builder = new SAXBuilder();
+		@SuppressWarnings("unused")
+		Document document;
+		try (InputStream fileInputStream = new BufferedInputStream(
+				new FileInputStream(recentFile))) {
+			document = builder.build(fileInputStream);
+		}
+		synchronized (recents) {
+			recents.clear();
+			//RecentDeserializer deserialiser = new RecentDeserializer();
+			try {
+				// recents.addAll(deserialiser.deserializeRecent(document
+				// .getRootElement()));
+			} catch (Exception e) {
+				logger.warn("Could not read recent workflows from file "
+						+ recentFile, e);
+			}
+		}
+	}
+
+	protected synchronized void saveRecent() {
+		File confDir = new File(applicationConfiguration.getApplicationHomeDir(), CONF);
+		confDir.mkdir();
+		File recentFile = new File(confDir, RECENT_WORKFLOWS_XML);
+
+		try {
+			saveRecent(recentFile);
+//		} catch (JDOMException e) {
+//			logger.warn("Could not generate XML for recent workflows to file "
+//					+ recentFile, e);
+		} catch (IOException e) {
+			logger.warn("Could not write recent workflows to file "
+					+ recentFile, e);
+		}
+	}
+
+	private void saveRecent(File recentFile) throws FileNotFoundException,
+			IOException {
+		// RecentSerializer serializer = new RecentSerializer();
+		// XMLOutputter outputter = new XMLOutputter();
+
+		// Element serializedRecent;
+		synchronized (recents) {
+			if (recents.size() > MAX_ITEMS)
+				// Remove excess entries
+				recents.subList(MAX_ITEMS, recents.size()).clear();
+			// serializedRecent = serializer.serializeRecent(recents);
+		}
+		try (OutputStream outputStream = new BufferedOutputStream(
+				new FileOutputStream(recentFile))) {
+			// outputter.output(serializedRecent, outputStream);
+		}
+	}
+
+	protected void updateRecentMenuGUI() {
+		int items = 0;
+		menu.removeAll();
+		synchronized (recents) {
+			for (Recent recent : recents) {
+				if (++items >= MAX_ITEMS)
+					break;
+				OpenRecentAction openRecentAction = new OpenRecentAction(
+						recent, fileManager);
+				if (fileManager.getDataflowBySource(recent.getDataflowSource()) != null)
+					openRecentAction.setEnabled(false);
+				// else setEnabled(true)
+				JMenuItem menuItem = new JMenuItem(openRecentAction);
+				if (items < 10) {
+					openRecentAction.putValue(NAME, items + " "
+							+ openRecentAction.getValue(NAME));
+					menuItem.setMnemonic(VK_0 + items);
+				}
+				menu.add(menuItem);
+			}
+		}
+		menu.setEnabled(items > 0);
+		menu.revalidate();
+	}
+
+	@SuppressWarnings("serial")
+	public static class OpenRecentAction extends AbstractAction implements
+			Runnable {
+		private final Recent recent;
+		private Component component = null;
+		private final FileManager fileManager;
+
+		public OpenRecentAction(Recent recent, FileManager fileManager) {
+			this.recent = recent;
+			this.fileManager = fileManager;
+			Serializable source = recent.getDataflowSource();
+			String name;
+			if (source instanceof File)
+				name = ((File) source).getAbsolutePath();
+			else
+				name = source.toString();
+			this.putValue(NAME, name);
+			this.putValue(SHORT_DESCRIPTION, "Open the workflow " + name);
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			component = null;
+			if (e.getSource() instanceof Component)
+				component = (Component) e.getSource();
+			setEnabled(false);
+			new Thread(this, "Opening workflow from "
+					+ recent.getDataflowSource()).start();
+		}
+
+		/**
+		 * Opening workflow in separate thread
+		 */
+		@Override
+		public void run() {
+			final Serializable source = recent.getDataflowSource();
+			try {
+				fileManager.openDataflow(recent.makefileType(), source);
+			} catch (OpenException ex) {
+				logger.warn("Failed to open the workflow from  " + source
+						+ " \n", ex);
+				showMessageDialog(component,
+						"Failed to open the workflow from url " + source
+								+ " \n" + ex.getMessage(), "Error!",
+						ERROR_MESSAGE);
+			} finally {
+				setEnabled(true);
+			}
+		}
+	}
+
+	@SuppressWarnings("serial")
+	public static class Recent implements Serializable {
+		private final class RecentFileType extends FileType {
+			@Override
+			public String getMimeType() {
+				return mimeType;
+			}
+
+			@Override
+			public String getExtension() {
+				return extension;
+			}
+
+			@Override
+			public String getDescription() {
+				return "File type " + extension + " " + mimeType;
+			}
+		}
+
+		private Serializable dataflowSource;
+		private String mimeType;
+		private String extension;
+
+		public String getMimeType() {
+			return mimeType;
+		}
+
+		public void setMimeType(String mimeType) {
+			this.mimeType = mimeType;
+		}
+
+		public String getExtension() {
+			return extension;
+		}
+
+		public void setExtension(String extension) {
+			this.extension = extension;
+		}
+
+		public Recent() {
+		}
+
+		public FileType makefileType() {
+			if (mimeType == null && extension == null)
+				return null;
+			return new RecentFileType();
+		}
+
+		public Recent(Serializable dataflowSource, FileType dataflowType) {
+			setDataflowSource(dataflowSource);
+			if (dataflowType != null) {
+				setMimeType(dataflowType.getMimeType());
+				setExtension(dataflowType.getExtension());
+			}
+		}
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime
+					* result
+					+ ((dataflowSource == null) ? 0 : dataflowSource.hashCode());
+			result = prime * result
+					+ ((extension == null) ? 0 : extension.hashCode());
+			result = prime * result
+					+ ((mimeType == null) ? 0 : mimeType.hashCode());
+			return result;
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (!(obj instanceof Recent))
+				return false;
+			Recent other = (Recent) obj;
+
+			if (dataflowSource == null) {
+				if (other.dataflowSource != null)
+					return false;
+			} else if (!dataflowSource.equals(other.dataflowSource))
+				return false;
+
+			if (extension == null) {
+				if (other.extension != null)
+					return false;
+			} else if (!extension.equals(other.extension))
+				return false;
+
+			if (mimeType == null) {
+				if (other.mimeType != null)
+					return false;
+			} else if (!mimeType.equals(other.mimeType))
+				return false;
+
+			return true;
+		}
+
+		public Serializable getDataflowSource() {
+			return dataflowSource;
+		}
+
+		public void setDataflowSource(Serializable dataflowSource) {
+			this.dataflowSource = dataflowSource;
+		}
+
+		@Override
+		public String toString() {
+			return getDataflowSource() + "";
+		}
+	}
+
+	// TODO find new serialization
+//	protected static class RecentDeserializer extends AbstractXMLDeserializer {
+//		public Collection<Recent> deserializeRecent(Element el) {
+//			return (Collection<Recent>) super.createBean(el, getClass()
+//					.getClassLoader());
+//		}
+//	}
+//
+//	protected static class RecentSerializer extends AbstractXMLSerializer {
+//		public Element serializeRecent(List<Recent> x) throws JDOMException,
+//				IOException {
+//			Element beanAsElement = super.beanAsElement(x);
+//			return beanAsElement;
+//		}
+//	}
+
+	public void setApplicationConfiguration(
+			ApplicationConfiguration applicationConfiguration) {
+		this.applicationConfiguration = applicationConfiguration;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveAllMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveAllMenuAction.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveAllMenuAction.java
new file mode 100644
index 0000000..ef10c2c
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveAllMenuAction.java
@@ -0,0 +1,46 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.menu;
+
+import static org.apache.taverna.workbench.file.impl.menu.FileSaveMenuSection.FILE_SAVE_SECTION_URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.impl.actions.SaveAllWorkflowsAction;
+
+public class FileSaveAllMenuAction extends AbstractMenuAction {
+	private final EditManager editManager;
+	private final FileManager fileManager;
+
+	public FileSaveAllMenuAction(EditManager editManager,
+			FileManager fileManager) {
+		super(FILE_SAVE_SECTION_URI, 30);
+		this.editManager = editManager;
+		this.fileManager = fileManager;
+	}
+
+	@Override
+	protected Action createAction() {
+		return new SaveAllWorkflowsAction(editManager, fileManager);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveAsMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveAsMenuAction.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveAsMenuAction.java
new file mode 100644
index 0000000..d868d42
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveAsMenuAction.java
@@ -0,0 +1,42 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.menu;
+
+import static org.apache.taverna.workbench.file.impl.menu.FileSaveMenuSection.FILE_SAVE_SECTION_URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.impl.actions.SaveWorkflowAsAction;
+
+public class FileSaveAsMenuAction extends AbstractMenuAction {
+	private final FileManager fileManager;
+
+	public FileSaveAsMenuAction(FileManager fileManager) {
+		super(FILE_SAVE_SECTION_URI, 20);
+		this.fileManager = fileManager;
+	}
+
+	@Override
+	protected Action createAction() {
+		return new SaveWorkflowAsAction(fileManager);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveMenuAction.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveMenuAction.java
new file mode 100644
index 0000000..5f042c8
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveMenuAction.java
@@ -0,0 +1,45 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.menu;
+
+import static org.apache.taverna.workbench.file.impl.menu.FileSaveMenuSection.FILE_SAVE_SECTION_URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.impl.actions.SaveWorkflowAction;
+
+public class FileSaveMenuAction extends AbstractMenuAction {
+	private final EditManager editManager;
+	private final FileManager fileManager;
+
+	public FileSaveMenuAction(EditManager editManager, FileManager fileManager) {
+		super(FILE_SAVE_SECTION_URI, 10);
+		this.editManager = editManager;
+		this.fileManager = fileManager;
+	}
+
+	@Override
+	protected Action createAction() {
+		return new SaveWorkflowAction(editManager, fileManager);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveMenuSection.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveMenuSection.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveMenuSection.java
new file mode 100644
index 0000000..4192ef5
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/FileSaveMenuSection.java
@@ -0,0 +1,35 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.menu;
+
+import java.net.URI;
+
+import org.apache.taverna.ui.menu.AbstractMenuSection;
+
+public class FileSaveMenuSection extends AbstractMenuSection {
+	public static final URI FILE_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#file");
+	public static final URI FILE_SAVE_SECTION_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#fileSaveSection");
+
+	public FileSaveMenuSection() {
+		super(FILE_URI, 40, FILE_SAVE_SECTION_URI);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/WorkflowsMenu.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/WorkflowsMenu.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/WorkflowsMenu.java
new file mode 100644
index 0000000..9219e94
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/menu/WorkflowsMenu.java
@@ -0,0 +1,162 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.menu;
+
+import static java.awt.event.KeyEvent.VK_0;
+import static java.awt.event.KeyEvent.VK_W;
+import static javax.swing.Action.MNEMONIC_KEY;
+import static javax.swing.SwingUtilities.invokeLater;
+import static org.apache.taverna.ui.menu.DefaultMenuBar.DEFAULT_MENU_BAR;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.ButtonGroup;
+import javax.swing.JMenu;
+import javax.swing.JRadioButtonMenuItem;
+
+import org.apache.taverna.lang.observer.Observable;
+import org.apache.taverna.lang.observer.Observer;
+import org.apache.taverna.ui.menu.AbstractMenuCustom;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.edits.EditManager.AbstractDataflowEditEvent;
+import org.apache.taverna.workbench.edits.EditManager.EditManagerEvent;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.events.AbstractDataflowEvent;
+import org.apache.taverna.workbench.file.events.FileManagerEvent;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+
+public class WorkflowsMenu extends AbstractMenuCustom {
+	private EditManagerObserver editManagerObserver = new EditManagerObserver();
+	private FileManager fileManager;
+	private FileManagerObserver fileManagerObserver = new FileManagerObserver();
+
+	private JMenu workflowsMenu;
+
+	public WorkflowsMenu(EditManager editManager, FileManager fileManager) {
+		super(DEFAULT_MENU_BAR, 900);
+		this.fileManager = fileManager;
+		fileManager.addObserver(fileManagerObserver);
+		editManager.addObserver(editManagerObserver);
+	}
+
+	@Override
+	protected Component createCustomComponent() {
+		DummyAction action = new DummyAction("Workflows");
+		action.putValue(MNEMONIC_KEY, VK_W);
+
+		workflowsMenu = new JMenu(action);
+
+		updateWorkflowsMenu();
+		return workflowsMenu;
+	}
+
+	public void updateWorkflowsMenu() {
+		invokeLater(new Runnable() {
+			@Override
+			public void run() {
+				updateWorkflowsMenuUI();
+			}
+		});
+	}
+
+	protected void updateWorkflowsMenuUI() {
+		workflowsMenu.setEnabled(false);
+		workflowsMenu.removeAll();
+		ButtonGroup workflowsGroup = new ButtonGroup();
+
+		int i = 0;
+		WorkflowBundle currentDataflow = fileManager.getCurrentDataflow();
+		for (WorkflowBundle workflowBundle : fileManager.getOpenDataflows()) {
+			String name = fileManager.getDataflowName(workflowBundle);
+			if (fileManager.isDataflowChanged(workflowBundle))
+				name = "*" + name;
+			// A counter
+			name = ++i + " " + name;
+
+			SwitchWorkflowAction switchWorkflowAction = new SwitchWorkflowAction(
+					name, workflowBundle);
+			if (i < 10)
+				switchWorkflowAction.putValue(MNEMONIC_KEY, new Integer(VK_0
+						+ i));
+
+			JRadioButtonMenuItem switchWorkflowMenuItem = new JRadioButtonMenuItem(
+					switchWorkflowAction);
+			workflowsGroup.add(switchWorkflowMenuItem);
+			if (workflowBundle.equals(currentDataflow))
+				switchWorkflowMenuItem.setSelected(true);
+			workflowsMenu.add(switchWorkflowMenuItem);
+		}
+		if (i == 0)
+			workflowsMenu.add(new NoWorkflowsOpen());
+		workflowsMenu.setEnabled(true);
+		workflowsMenu.revalidate();
+	}
+
+	private final class EditManagerObserver implements
+			Observer<EditManagerEvent> {
+		@Override
+		public void notify(Observable<EditManagerEvent> sender,
+				EditManagerEvent message) throws Exception {
+			if (message instanceof AbstractDataflowEditEvent)
+				updateWorkflowsMenu();
+		}
+	}
+
+	private final class FileManagerObserver implements
+			Observer<FileManagerEvent> {
+		@Override
+		public void notify(Observable<FileManagerEvent> sender,
+				FileManagerEvent message) throws Exception {
+			if (message instanceof AbstractDataflowEvent)
+				updateWorkflowsMenu();
+			// TODO: Don't rebuild whole menu
+		}
+	}
+
+	@SuppressWarnings("serial")
+	private final class NoWorkflowsOpen extends AbstractAction {
+		private NoWorkflowsOpen() {
+			super("No workflows open");
+			setEnabled(false);
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			// No-op
+		}
+	}
+
+	@SuppressWarnings("serial")
+	private final class SwitchWorkflowAction extends AbstractAction {
+		private final WorkflowBundle workflowBundle;
+
+		private SwitchWorkflowAction(String name, WorkflowBundle workflowBundle) {
+			super(name);
+			this.workflowBundle = workflowBundle;
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			fileManager.setCurrentDataflow(workflowBundle);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/CloseToolbarAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/CloseToolbarAction.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/CloseToolbarAction.java
new file mode 100644
index 0000000..d99d3d2
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/CloseToolbarAction.java
@@ -0,0 +1,54 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.toolbar;
+
+import static org.apache.taverna.workbench.file.impl.toolbar.FileToolbarMenuSection.FILE_TOOLBAR_SECTION;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.impl.actions.CloseWorkflowAction;
+
+/**
+ * Action to close the current workflow.
+ * 
+ * @author Alex Nenadic
+ */
+public class CloseToolbarAction extends AbstractMenuAction {
+	private static final URI FILE_CLOSE_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#fileToolbarClose");
+	private final EditManager editManager;
+	private final FileManager fileManager;
+
+	public CloseToolbarAction(EditManager editManager, FileManager fileManager) {
+		super(FILE_TOOLBAR_SECTION, 30, FILE_CLOSE_URI);
+		this.editManager = editManager;
+		this.fileManager = fileManager;
+	}
+
+	@Override
+	protected Action createAction() {
+		return new CloseWorkflowAction(editManager, fileManager);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/FileToolbarMenuSection.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/FileToolbarMenuSection.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/FileToolbarMenuSection.java
new file mode 100644
index 0000000..7b2b484
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/FileToolbarMenuSection.java
@@ -0,0 +1,35 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.toolbar;
+
+import static org.apache.taverna.ui.menu.DefaultToolBar.DEFAULT_TOOL_BAR;
+
+import java.net.URI;
+
+import org.apache.taverna.ui.menu.AbstractMenuSection;
+
+public class FileToolbarMenuSection extends AbstractMenuSection {
+	public static final URI FILE_TOOLBAR_SECTION = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#fileToolbarSection");
+
+	public FileToolbarMenuSection() {
+		super(DEFAULT_TOOL_BAR, 10, FILE_TOOLBAR_SECTION);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/NewToolbarAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/NewToolbarAction.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/NewToolbarAction.java
new file mode 100644
index 0000000..a39e1ad
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/NewToolbarAction.java
@@ -0,0 +1,46 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.toolbar;
+
+import static org.apache.taverna.workbench.file.impl.toolbar.FileToolbarMenuSection.FILE_TOOLBAR_SECTION;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.impl.actions.NewWorkflowAction;
+
+public class NewToolbarAction extends AbstractMenuAction {
+	private static final URI FILE_NEW_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#fileToolbarNew");
+	private final FileManager fileManager;
+
+	public NewToolbarAction(FileManager fileManager) {
+		super(FILE_TOOLBAR_SECTION, 10, FILE_NEW_URI);
+		this.fileManager = fileManager;
+	}
+
+	@Override
+	protected Action createAction() {
+		return new NewWorkflowAction(fileManager);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/OpenToolbarAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/OpenToolbarAction.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/OpenToolbarAction.java
new file mode 100644
index 0000000..09b9f52
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/OpenToolbarAction.java
@@ -0,0 +1,46 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.toolbar;
+
+import static org.apache.taverna.workbench.file.impl.toolbar.FileToolbarMenuSection.FILE_TOOLBAR_SECTION;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.impl.actions.OpenWorkflowAction;
+
+public class OpenToolbarAction extends AbstractMenuAction {
+	private static final URI FILE_OPEN_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#fileToolbarOpen");
+	private final FileManager fileManager;
+
+	public OpenToolbarAction(FileManager fileManager) {
+		super(FILE_TOOLBAR_SECTION, 20, FILE_OPEN_URI);
+		this.fileManager = fileManager;
+	}
+
+	@Override
+	protected Action createAction() {
+		return new OpenWorkflowAction(fileManager);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/OpenWorkflowFromURLToolbarAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/OpenWorkflowFromURLToolbarAction.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/OpenWorkflowFromURLToolbarAction.java
new file mode 100644
index 0000000..cd4c91e
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/OpenWorkflowFromURLToolbarAction.java
@@ -0,0 +1,46 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.toolbar;
+
+import static org.apache.taverna.workbench.file.impl.toolbar.FileToolbarMenuSection.FILE_TOOLBAR_SECTION;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.impl.actions.OpenWorkflowFromURLAction;
+
+public class OpenWorkflowFromURLToolbarAction extends AbstractMenuAction {
+	private static final URI FILE_OPEN_FROM_URL_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#fileToolbarOpenFromURL");
+	private final FileManager fileManager;
+
+	public OpenWorkflowFromURLToolbarAction(FileManager fileManager) {
+		super(FILE_TOOLBAR_SECTION, 25, FILE_OPEN_FROM_URL_URI);
+		this.fileManager = fileManager;
+	}
+
+	@Override
+	protected Action createAction() {
+		return new OpenWorkflowFromURLAction(null, fileManager);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/SaveToolbarAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/SaveToolbarAction.java b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/SaveToolbarAction.java
new file mode 100644
index 0000000..fc06660
--- /dev/null
+++ b/taverna-file-impl/src/main/java/org/apache/taverna/workbench/file/impl/toolbar/SaveToolbarAction.java
@@ -0,0 +1,49 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.file.impl.toolbar;
+
+import static org.apache.taverna.workbench.file.impl.toolbar.FileToolbarMenuSection.FILE_TOOLBAR_SECTION;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.impl.actions.SaveWorkflowAction;
+
+public class SaveToolbarAction extends AbstractMenuAction {
+	private static final URI FILE_SAVE_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#fileToolbarSave");
+	private final EditManager editManager;
+	private final FileManager fileManager;
+
+	public SaveToolbarAction(EditManager editManager, FileManager fileManager) {
+		super(FILE_TOOLBAR_SECTION, 40, FILE_SAVE_URI);
+		this.editManager = editManager;
+		this.fileManager = fileManager;
+	}
+
+	@Override
+	protected Action createAction() {
+		return new SaveWorkflowAction(editManager, fileManager);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.ui.menu.MenuComponent
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.ui.menu.MenuComponent b/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.ui.menu.MenuComponent
index 100915c..081aa6c 100644
--- a/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.ui.menu.MenuComponent
+++ b/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.ui.menu.MenuComponent
@@ -1,20 +1,20 @@
-net.sf.taverna.t2.workbench.file.impl.menu.FileCloseMenuAction
-net.sf.taverna.t2.workbench.file.impl.menu.FileNewMenuAction
-net.sf.taverna.t2.workbench.file.impl.menu.FileOpenMenuAction
-net.sf.taverna.t2.workbench.file.impl.menu.FileOpenFromURLMenuAction
-net.sf.taverna.t2.workbench.file.impl.menu.FileOpenMenuSection
-net.sf.taverna.t2.workbench.file.impl.menu.FileOpenRecentMenuAction
-net.sf.taverna.t2.workbench.file.impl.menu.FileSaveMenuSection
-net.sf.taverna.t2.workbench.file.impl.menu.FileSaveMenuAction
-net.sf.taverna.t2.workbench.file.impl.menu.FileSaveAllMenuAction
-net.sf.taverna.t2.workbench.file.impl.menu.FileSaveAsMenuAction
+org.apache.taverna.workbench.file.impl.menu.FileCloseMenuAction
+org.apache.taverna.workbench.file.impl.menu.FileNewMenuAction
+org.apache.taverna.workbench.file.impl.menu.FileOpenMenuAction
+org.apache.taverna.workbench.file.impl.menu.FileOpenFromURLMenuAction
+org.apache.taverna.workbench.file.impl.menu.FileOpenMenuSection
+org.apache.taverna.workbench.file.impl.menu.FileOpenRecentMenuAction
+org.apache.taverna.workbench.file.impl.menu.FileSaveMenuSection
+org.apache.taverna.workbench.file.impl.menu.FileSaveMenuAction
+org.apache.taverna.workbench.file.impl.menu.FileSaveAllMenuAction
+org.apache.taverna.workbench.file.impl.menu.FileSaveAsMenuAction
 
-net.sf.taverna.t2.workbench.file.impl.menu.WorkflowsMenu
-net.sf.taverna.t2.workbench.file.impl.menu.FileCloseAllMenuAction
+org.apache.taverna.workbench.file.impl.menu.WorkflowsMenu
+org.apache.taverna.workbench.file.impl.menu.FileCloseAllMenuAction
 
-net.sf.taverna.t2.workbench.file.impl.toolbar.FileToolbarMenuSection
-net.sf.taverna.t2.workbench.file.impl.toolbar.NewToolbarAction
-net.sf.taverna.t2.workbench.file.impl.toolbar.OpenToolbarAction
-net.sf.taverna.t2.workbench.file.impl.toolbar.OpenWorkflowFromURLToolbarAction
-net.sf.taverna.t2.workbench.file.impl.toolbar.SaveToolbarAction
-net.sf.taverna.t2.workbench.file.impl.toolbar.CloseToolbarAction
+org.apache.taverna.workbench.file.impl.toolbar.FileToolbarMenuSection
+org.apache.taverna.workbench.file.impl.toolbar.NewToolbarAction
+org.apache.taverna.workbench.file.impl.toolbar.OpenToolbarAction
+org.apache.taverna.workbench.file.impl.toolbar.OpenWorkflowFromURLToolbarAction
+org.apache.taverna.workbench.file.impl.toolbar.SaveToolbarAction
+org.apache.taverna.workbench.file.impl.toolbar.CloseToolbarAction

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.ShutdownSPI
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.ShutdownSPI b/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.ShutdownSPI
index cc53d36..7ac50c7 100644
--- a/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.ShutdownSPI
+++ b/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.ShutdownSPI
@@ -1 +1 @@
-net.sf.taverna.t2.workbench.file.impl.hooks.CloseWorkflowsOnShutdown
+org.apache.taverna.workbench.file.impl.hooks.CloseWorkflowsOnShutdown

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.file.DataflowPersistenceHandler
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.file.DataflowPersistenceHandler b/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.file.DataflowPersistenceHandler
index cfd1c7a..664e774 100644
--- a/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.file.DataflowPersistenceHandler
+++ b/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.file.DataflowPersistenceHandler
@@ -1,2 +1,2 @@
-net.sf.taverna.t2.workbench.file.impl.T2DataflowOpener
-net.sf.taverna.t2.workbench.file.impl.DataflowFromDataflowPersistenceHandler
\ No newline at end of file
+org.apache.taverna.workbench.file.impl.T2DataflowOpener
+org.apache.taverna.workbench.file.impl.DataflowFromDataflowPersistenceHandler
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.file.FileManager
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.file.FileManager b/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.file.FileManager
index 656feeb..e7021d9 100644
--- a/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.file.FileManager
+++ b/taverna-file-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.file.FileManager
@@ -1 +1 @@
-net.sf.taverna.t2.workbench.file.impl.FileManagerImpl
\ No newline at end of file
+org.apache.taverna.workbench.file.impl.FileManagerImpl
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-file-impl/src/test/java/net/sf/taverna/t2/workbench/file/impl/FileManagerTest.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/test/java/net/sf/taverna/t2/workbench/file/impl/FileManagerTest.java b/taverna-file-impl/src/test/java/net/sf/taverna/t2/workbench/file/impl/FileManagerTest.java
deleted file mode 100644
index d31825a..0000000
--- a/taverna-file-impl/src/test/java/net/sf/taverna/t2/workbench/file/impl/FileManagerTest.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- *  Modifications to the initial code base are copyright of their
- *  respective authors, or their employers as appropriate.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public License
- *  as published by the Free Software Foundation; either version 2.1 of
- *  the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- ******************************************************************************/
-package net.sf.taverna.t2.workbench.file.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.taverna.lang.observer.Observable;
-import org.apache.taverna.lang.observer.Observer;
-import org.apache.taverna.workbench.edits.Edit;
-import org.apache.taverna.workbench.edits.EditManager;
-import org.apache.taverna.workbench.edits.impl.EditManagerImpl;
-import org.apache.taverna.workbench.file.DataflowInfo;
-import org.apache.taverna.workbench.file.DataflowPersistenceHandler;
-import org.apache.taverna.workbench.file.FileManager;
-import org.apache.taverna.workbench.file.events.FileManagerEvent;
-import org.apache.taverna.workbench.file.events.SetCurrentDataflowEvent;
-import org.apache.taverna.workbench.file.exceptions.OpenException;
-import org.apache.taverna.workbench.file.exceptions.OverwriteException;
-import org.apache.taverna.workflow.edits.AddProcessorEdit;
-import org.apache.taverna.workflow.edits.RenameEdit;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import org.apache.taverna.scufl2.api.container.WorkflowBundle;
-import org.apache.taverna.scufl2.api.core.Processor;
-import org.apache.taverna.scufl2.api.core.Workflow;
-import org.apache.taverna.scufl2.api.io.WorkflowBundleIO;
-import org.apache.taverna.scufl2.api.io.WorkflowBundleReader;
-import org.apache.taverna.scufl2.api.io.WorkflowBundleWriter;
-import org.apache.taverna.scufl2.rdfxml.RDFXMLReader;
-import org.apache.taverna.scufl2.rdfxml.RDFXMLWriter;
-import org.apache.taverna.scufl2.translator.t2flow.T2FlowReader;
-
-public class FileManagerTest {
-
-	private static final WorkflowBundleFileType WF_BUNDLE_FILE_TYPE = new WorkflowBundleFileType();
-	private static final T2FlowFileType T2_FLOW_FILE_TYPE = new T2FlowFileType();
-
-	private static final String DUMMY_WORKFLOW_T2FLOW = "dummy-workflow.t2flow";
-
-	private FileManagerImpl fileManager;
-	private EditManager editManager;
-
-	private FileManagerObserver fileManagerObserver= new FileManagerObserver();;
-
-	@Test
-	public void close() throws Exception {
-		assertTrue("Non-empty set of open dataflows", fileManager
-				.getOpenDataflows().isEmpty());
-		WorkflowBundle dataflow = openDataflow();
-		assertEquals("Unexpected list of open dataflows", Arrays
-				.asList(dataflow), fileManager.getOpenDataflows());
-		fileManager.closeDataflow(dataflow, true);
-		assertNotSame(dataflow, fileManager.getOpenDataflows().get(0));
-		assertTrue("Did not insert empty dataflow after close", fileManager
-				.getOpenDataflows().get(0).getMainWorkflow().getProcessors().isEmpty());
-	}
-
-	@Test
-	public void openRemovesEmptyDataflow() throws Exception {
-		WorkflowBundle newDataflow = fileManager.newDataflow();
-		assertEquals("Unexpected list of open dataflows", Arrays
-				.asList(newDataflow), fileManager.getOpenDataflows());
-		WorkflowBundle dataflow = openDataflow();
-		// Should have removed newDataflow
-		assertEquals("Unexpected list of open dataflows", Arrays
-				.asList(dataflow), fileManager.getOpenDataflows());
-	}
-
-	@Test
-	public void isChanged() throws Exception {
-		WorkflowBundle dataflow = openDataflow();
-		assertFalse("Dataflow should not have changed", fileManager
-				.isDataflowChanged(dataflow));
-
-		// Do a change
-		Processor emptyProcessor = new Processor();
-		Edit<Workflow> addProcessorEdit = new AddProcessorEdit(dataflow.getMainWorkflow(),
-				emptyProcessor);
-		editManager.doDataflowEdit(dataflow, addProcessorEdit);
-		assertTrue("Dataflow should have changed", fileManager
-				.isDataflowChanged(dataflow));
-
-		// Save it with the change
-		File dataflowFile = File.createTempFile("test", ".t2flow");
-		dataflowFile.deleteOnExit();
-		dataflowFile.delete();
-
-		fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, false);
-		assertFalse("Dataflow should no longer be marked as changed",
-				fileManager.isDataflowChanged(dataflow));
-	}
-
-	@Ignore("Undo support for ischanged not yet implemented")
-	@Test
-	public void isChangedWithUndo() throws Exception {
-		WorkflowBundle dataflow = openDataflow();
-		// Do a change
-		Processor emptyProcessor = new Processor();
-		Edit<Workflow> addProcessorEdit = new AddProcessorEdit(dataflow.getMainWorkflow(),
-				emptyProcessor);
-		editManager.doDataflowEdit(dataflow, addProcessorEdit);
-		assertTrue("Dataflow should have changed", fileManager
-				.isDataflowChanged(dataflow));
-		editManager.undoDataflowEdit(dataflow);
-		assertFalse(
-				"Dataflow should no longer be marked as changed after undo",
-				fileManager.isDataflowChanged(dataflow));
-		editManager.redoDataflowEdit(dataflow);
-		assertTrue("Dataflow should have changed after redo before save",
-				fileManager.isDataflowChanged(dataflow));
-
-		// Save it with the change
-		File dataflowFile = File.createTempFile("test", ".t2flow");
-		dataflowFile.deleteOnExit();
-		dataflowFile.delete();
-		fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, false);
-		assertFalse("Dataflow should no longer be marked as changed",
-				fileManager.isDataflowChanged(dataflow));
-
-		editManager.undoDataflowEdit(dataflow);
-		assertTrue("Dataflow should have changed after undo", fileManager
-				.isDataflowChanged(dataflow));
-		fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, false);
-		editManager.redoDataflowEdit(dataflow);
-		assertTrue("Dataflow should have changed after redo after save",
-				fileManager.isDataflowChanged(dataflow));
-	}
-
-	@Test
-	public void isListed() throws Exception {
-		assertTrue("Non-empty set of open data flows", fileManager
-				.getOpenDataflows().isEmpty());
-		WorkflowBundle dataflow = openDataflow();
-		assertEquals("Unexpected list of open dataflows", Arrays
-				.asList(dataflow), fileManager.getOpenDataflows());
-	}
-
-	/**
-	 * Always uses a <strong>new</strong> file manager instead of the instance
-	 * one from {@link FileManager#getInstance()}.
-	 *
-	 * @see #getFileManagerInstance()
-	 *
-	 */
-	@Before
-	public void makeFileManager() {
-		System.setProperty("java.awt.headless", "true");
-		editManager = new EditManagerImpl();
-		fileManager = new FileManagerImpl(editManager);
-		fileManagerObserver = new FileManagerObserver();
-		fileManager.addObserver(fileManagerObserver);
-		WorkflowBundleIO workflowBundleIO = new WorkflowBundleIO();
-		workflowBundleIO.setReaders(Arrays.<WorkflowBundleReader>asList(new RDFXMLReader(), new T2FlowReader()));
-		workflowBundleIO.setWriters(Arrays.<WorkflowBundleWriter>asList(new RDFXMLWriter()));
-		T2DataflowOpener t2DataflowOpener = new T2DataflowOpener();
-		t2DataflowOpener.setWorkflowBundleIO(workflowBundleIO);
-		WorkflowBundleOpener workflowBundleOpener = new WorkflowBundleOpener();
-		workflowBundleOpener.setWorkflowBundleIO(workflowBundleIO);
-		WorkflowBundleSaver workflowBundleSaver = new WorkflowBundleSaver();
-		workflowBundleSaver.setWorkflowBundleIO(workflowBundleIO);
-		DataflowPersistenceHandlerRegistry dataflowPersistenceHandlerRegistry = new DataflowPersistenceHandlerRegistry();
-		dataflowPersistenceHandlerRegistry.setDataflowPersistenceHandlers(Arrays.asList(
-				new DataflowPersistenceHandler[] {t2DataflowOpener, workflowBundleOpener, workflowBundleSaver}));
-		dataflowPersistenceHandlerRegistry.updateColletions();
-		fileManager.setDataflowPersistenceHandlerRegistry(dataflowPersistenceHandlerRegistry);
-	}
-
-	@Test
-	public void open() throws Exception {
-		assertTrue("ModelMapObserver already contained messages",
-				fileManagerObserver.messages.isEmpty());
-		WorkflowBundle dataflow = openDataflow();
-		assertNotNull("Dataflow was not loaded", dataflow);
-		assertEquals("Loaded dataflow was not set as current dataflow",
-				dataflow, fileManager.getCurrentDataflow());
-		assertFalse("ModelMapObserver did not contain message",
-				fileManagerObserver.messages.isEmpty());
-		assertEquals("ModelMapObserver contained unexpected messages", 2,
-				fileManagerObserver.messages.size());
-		FileManagerEvent event = fileManagerObserver.messages.get(0);
-		assertTrue(event instanceof SetCurrentDataflowEvent);
-		assertEquals(dataflow, ((SetCurrentDataflowEvent) event).getDataflow());
-	}
-
-	@Test
-	public void openSilently() throws Exception {
-		assertTrue("ModelMapObserver already contained messages",
-				fileManagerObserver.messages.isEmpty());
-		URL url = getClass().getResource(DUMMY_WORKFLOW_T2FLOW);
-		DataflowInfo info = fileManager.openDataflowSilently(T2_FLOW_FILE_TYPE, url);
-
-		WorkflowBundle dataflow = info.getDataflow();
-		assertNotNull("Dataflow was not loaded", dataflow);
-
-		assertNotSame("Loaded dataflow was set as current dataflow",
-				dataflow, fileManager.getCurrentDataflow());
-		assertTrue("ModelMapObserver contained unexpected messages",
-				fileManagerObserver.messages.isEmpty());
-	}
-
-	@Test
-	public void canSaveDataflow() throws Exception {
-		WorkflowBundle savedDataflow = openDataflow();
-		File dataflowFile = File.createTempFile("test", ".t2flow");
-		dataflowFile.deleteOnExit();
-		dataflowFile.delete();
-		fileManager.saveDataflow(savedDataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, true);
-		assertTrue(fileManager.canSaveWithoutDestination(savedDataflow));
-		fileManager.saveDataflow(savedDataflow, true);
-		fileManager.closeDataflow(savedDataflow, true);
-
-		WorkflowBundle otherFlow = fileManager.openDataflow(WF_BUNDLE_FILE_TYPE, dataflowFile.toURI()
-				.toURL());
-		assertTrue(fileManager.canSaveWithoutDestination(otherFlow));
-	}
-
-	@Test
-	public void save() throws Exception {
-		WorkflowBundle savedDataflow = openDataflow();
-		File dataflowFile = File.createTempFile("test", ".t2flow");
-		dataflowFile.deleteOnExit();
-		dataflowFile.delete();
-		assertFalse("File should not exist", dataflowFile.isFile());
-		fileManager.saveDataflow(savedDataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, false);
-		assertTrue("File should exist", dataflowFile.isFile());
-		WorkflowBundle loadedDataflow = fileManager.openDataflow(WF_BUNDLE_FILE_TYPE, dataflowFile.toURI()
-				.toURL());
-		assertNotSame("Dataflow was not reopened", savedDataflow,
-				loadedDataflow);
-		assertEquals("Unexpected number of processors in saved dataflow", 1,
-				savedDataflow.getMainWorkflow().getProcessors().size());
-		assertEquals("Unexpected number of processors in loaded dataflow", 1,
-				loadedDataflow.getMainWorkflow().getProcessors().size());
-
-		Processor savedProcessor = savedDataflow.getMainWorkflow().getProcessors().first();
-		Processor loadedProcessor = loadedDataflow.getMainWorkflow().getProcessors().first();
-		assertEquals("Loaded processor had wrong name", savedProcessor
-				.getName(), loadedProcessor.getName());
-
-		// TODO convert to scufl2
-//		BeanshellActivity savedActivity = (BeanshellActivity) savedProcessor
-//				.getActivityList().get(0);
-//		BeanshellActivity loadedActivity = (BeanshellActivity) loadedProcessor
-//				.getActivityList().get(0);
-//		String savedScript = savedActivity.getConfiguration().getScript();
-//		String loadedScript = loadedActivity.getConfiguration().getScript();
-//		assertEquals("Unexpected saved script",
-//				"String output = input + \"XXX\";", savedScript);
-//		assertEquals("Loaded script did not matched saved script", savedScript,
-//				loadedScript);
-	}
-
-	@Test
-	public void saveSilent() throws Exception {
-		assertTrue("ModelMapObserver contained unexpected messages",
-				fileManagerObserver.messages.isEmpty());
-
-		URL url = getClass().getResource(DUMMY_WORKFLOW_T2FLOW);
-		DataflowInfo info = fileManager.openDataflowSilently(T2_FLOW_FILE_TYPE, url);
-		WorkflowBundle dataflow = info.getDataflow();
-		assertTrue("ModelMapObserver contained unexpected messages",
-				fileManagerObserver.messages.isEmpty());
-
-		File dataflowFile = File.createTempFile("test", ".t2flow");
-		dataflowFile.deleteOnExit();
-		dataflowFile.delete();
-		assertFalse("File should not exist", dataflowFile.isFile());
-
-		fileManager.saveDataflowSilently(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, false);
-		assertTrue("File should exist", dataflowFile.isFile());
-
-		assertTrue("ModelMapObserver contained unexpected messages",
-				fileManagerObserver.messages.isEmpty());
-
-	}
-
-	@Test
-	public void saveOverwriteAgain() throws Exception {
-		WorkflowBundle dataflow = openDataflow();
-		File dataflowFile = File.createTempFile("test", ".t2flow");
-		dataflowFile.delete();
-		dataflowFile.deleteOnExit();
-		// File did NOT exist, should not fail
-		fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, true);
-
-		Processor processor = dataflow.getMainWorkflow().getProcessors().first();
-		Edit<Processor> renameEdit = new RenameEdit<Processor>(processor,
-				processor.getName() + "-changed");
-		editManager.doDataflowEdit(dataflow, renameEdit);
-
-		// Last save was OURs, so should *not* fail - even if we now use
-		// the specific saveDataflow() method
-		fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, true);
-
-		//Thread.sleep(1500);
-		WorkflowBundle otherFlow = openDataflow();
-		// Saving another flow to same file should still fail
-		try {
-			fileManager.saveDataflow(otherFlow,WF_BUNDLE_FILE_TYPE, dataflowFile, true);
-			fail("Should have thrown OverwriteException");
-		} catch (OverwriteException ex) {
-			// Expected
-		}
-	}
-
-	@Test(expected = OverwriteException.class)
-	public void saveOverwriteWarningFails() throws Exception {
-		WorkflowBundle dataflow = openDataflow();
-		File dataflowFile = File.createTempFile("test", ".t2flow");
-		dataflowFile.deleteOnExit();
-		// Should fail as file already exists
-		fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, true);
-	}
-
-	@Test
-	public void saveOverwriteWarningWorks() throws Exception {
-		WorkflowBundle dataflow = openDataflow();
-		File dataflowFile = File.createTempFile("test", ".t2flow");
-		dataflowFile.delete();
-		dataflowFile.deleteOnExit();
-		// File did NOT exist, should not fail
-		fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, true);
-	}
-
-	@After
-	public void stopListeningToModelMap() {
-		fileManager.removeObserver(fileManagerObserver);
-	}
-
-	protected WorkflowBundle openDataflow() throws OpenException {
-		URL url = getClass().getResource(DUMMY_WORKFLOW_T2FLOW);
-		assertNotNull(url);
-		WorkflowBundle dataflow = fileManager.openDataflow(T2_FLOW_FILE_TYPE, url);
-		assertNotNull(dataflow);
-		return dataflow;
-	}
-
-	private final class FileManagerObserver implements Observer<FileManagerEvent> {
-		protected List<FileManagerEvent> messages = new ArrayList<FileManagerEvent>();
-
-		@Override
-		public void notify(Observable<FileManagerEvent> sender, FileManagerEvent message) throws Exception {
-			messages.add(message);
-			if (message instanceof SetCurrentDataflowEvent) {
-				assertTrue("Dataflow was not listed as open when set current",
-						fileManager.getOpenDataflows().contains(
-								((SetCurrentDataflowEvent) message).getDataflow()));
-			}
-		}
-	}
-
-}