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/26 19:52:10 UTC

[21/51] [partial] incubator-taverna-workbench git commit: all packages are moved to org.apache.taverna.*

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/AbstractUndoAction.java
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/AbstractUndoAction.java b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/AbstractUndoAction.java
new file mode 100644
index 0000000..0f024a1
--- /dev/null
+++ b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/AbstractUndoAction.java
@@ -0,0 +1,165 @@
+/*
+* 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.edits.impl.menu;
+
+import static java.awt.Toolkit.getDefaultToolkit;
+import static java.awt.event.KeyEvent.VK_Y;
+import static java.awt.event.KeyEvent.VK_Z;
+import static javax.swing.KeyStroke.getKeyStroke;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.redoIcon;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.undoIcon;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+
+import org.apache.taverna.lang.observer.Observable;
+import org.apache.taverna.lang.observer.Observer;
+import org.apache.taverna.lang.observer.SwingAwareObserver;
+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.selection.SelectionManager;
+import org.apache.taverna.workbench.selection.events.PerspectiveSelectionEvent;
+import org.apache.taverna.workbench.selection.events.SelectionManagerEvent;
+import org.apache.taverna.workbench.selection.events.WorkflowBundleSelectionEvent;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+
+/**
+ * @author David Withers
+ */
+@SuppressWarnings("serial")
+public abstract class AbstractUndoAction extends AbstractAction {
+	protected EditManager editManager;
+	private SelectionManager selectionManager;
+
+	public AbstractUndoAction(String label, EditManager editManager) {
+		super(label);
+		this.editManager = editManager;
+		if (label.equals("Undo")) {
+			this.putValue(SMALL_ICON, undoIcon);
+			this.putValue(SHORT_DESCRIPTION, "Undo an action");
+			putValue(
+					ACCELERATOR_KEY,
+					getKeyStroke(VK_Z, getDefaultToolkit()
+							.getMenuShortcutKeyMask()));
+		} else if (label.equals("Redo")) {
+			this.putValue(SMALL_ICON, redoIcon);
+			this.putValue(SHORT_DESCRIPTION, "Redo an action");
+			putValue(
+					ACCELERATOR_KEY,
+					getKeyStroke(VK_Y, getDefaultToolkit()
+							.getMenuShortcutKeyMask()));
+		}
+		editManager.addObserver(new EditManagerObserver());
+		updateStatus();
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		WorkflowBundle workflowBundle = getCurrentDataflow();
+		if (workflowBundle != null)
+			performUndoOrRedo(workflowBundle);
+	}
+
+	/**
+	 * Check if action should be enabled or disabled and update its status.
+	 */
+	public void updateStatus() {
+		WorkflowBundle workflowBundle = getCurrentDataflow();
+		if (workflowBundle == null)
+			setEnabled(false);
+		setEnabled(isActive(workflowBundle));
+	}
+
+	/**
+	 * Retrieve the current dataflow from the {@link ModelMap}, or
+	 * <code>null</code> if no workflow is active.
+	 * 
+	 * @return The current {@link Dataflow}
+	 */
+	protected WorkflowBundle getCurrentDataflow() {
+		if (selectionManager == null)
+			return null;
+		return selectionManager.getSelectedWorkflowBundle();
+	}
+
+	/**
+	 * Return <code>true</code> if the action should be enabled when the given
+	 * {@link Dataflow} is the current, ie. if it's undoable or redoable.
+	 * 
+	 * @param dataflow
+	 *            Current {@link Dataflow}
+	 * @return <code>true</code> if the action should be enabled.
+	 */
+	protected abstract boolean isActive(WorkflowBundle workflowBundle);
+
+	/**
+	 * Called by {@link #actionPerformed(ActionEvent)} when the current dataflow
+	 * is not <code>null</code>.
+	 * 
+	 * @param dataflow
+	 *            {@link Dataflow} on which to undo or redo
+	 */
+	protected abstract void performUndoOrRedo(WorkflowBundle workflowBundle);
+
+	public void setSelectionManager(SelectionManager selectionManager) {
+		this.selectionManager = selectionManager;
+		if (selectionManager != null)
+			selectionManager.addObserver(new SelectionManagerObserver());
+	}
+
+	/**
+	 * Update the status if there's been an edit done on the current workflow.
+	 * 
+	 */
+	protected class EditManagerObserver implements Observer<EditManagerEvent> {
+		@Override
+		public void notify(Observable<EditManagerEvent> sender,
+				EditManagerEvent message) throws Exception {
+			if (!(message instanceof AbstractDataflowEditEvent))
+				return;
+			AbstractDataflowEditEvent dataflowEdit = (AbstractDataflowEditEvent) message;
+			if (dataflowEdit.getDataFlow().equals(dataflowEdit.getDataFlow()))
+				// It's an edit that could effect our undoability
+				updateStatus();
+		}
+	}
+
+	private final class SelectionManagerObserver extends
+			SwingAwareObserver<SelectionManagerEvent> {
+		private static final String DESIGN_PERSPECTIVE_ID = "net.sf.taverna.t2.ui.perspectives.design.DesignPerspective";
+
+		@Override
+		public void notifySwing(Observable<SelectionManagerEvent> sender,
+				SelectionManagerEvent message) {
+			if (message instanceof WorkflowBundleSelectionEvent)
+				updateStatus();
+			else if (message instanceof PerspectiveSelectionEvent) {
+				PerspectiveSelectionEvent perspectiveSelectionEvent = (PerspectiveSelectionEvent) message;
+				if (DESIGN_PERSPECTIVE_ID.equals(perspectiveSelectionEvent
+						.getSelectedPerspective().getID()))
+					updateStatus();
+				else
+					setEnabled(false);
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/RedoMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/RedoMenuAction.java b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/RedoMenuAction.java
new file mode 100644
index 0000000..3696458
--- /dev/null
+++ b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/RedoMenuAction.java
@@ -0,0 +1,85 @@
+/*
+* 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.edits.impl.menu;
+
+import static javax.swing.JOptionPane.ERROR_MESSAGE;
+import static javax.swing.JOptionPane.showMessageDialog;
+import static org.apache.taverna.workbench.edits.impl.menu.UndoMenuSection.UNDO_SECTION_URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.edits.Edit;
+import org.apache.taverna.workbench.edits.EditException;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.selection.SelectionManager;
+
+import org.apache.log4j.Logger;
+
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+
+/**
+ * Redo the previous {@link Edit} done on the current workflow using the
+ * {@link EditManager}.
+ *
+ * @author Stian Soiland-Reyes
+ */
+public class RedoMenuAction extends AbstractMenuAction {
+	private static Logger logger = Logger.getLogger(RedoMenuAction.class);
+	private final EditManager editManager;
+	private SelectionManager selectionManager;
+	private AbstractUndoAction undoAction;
+
+	public RedoMenuAction(EditManager editManager) {
+		super(UNDO_SECTION_URI, 20);
+		this.editManager = editManager;
+	}
+
+	@SuppressWarnings("serial")
+	@Override
+	protected Action createAction() {
+		undoAction = new AbstractUndoAction("Redo", editManager) {
+			@Override
+			protected boolean isActive(WorkflowBundle workflowBundle) {
+				return editManager.canRedoDataflowEdit(workflowBundle);
+			}
+
+			@Override
+			protected void performUndoOrRedo(WorkflowBundle workflowBundle) {
+				try {
+					editManager.redoDataflowEdit(workflowBundle);
+				} catch (EditException | RuntimeException e) {
+					logger.warn("Could not redo for " + workflowBundle, e);
+					showMessageDialog(null, "Could not redo for workflow "
+							+ workflowBundle + ":\n" + e, "Could not redo",
+							ERROR_MESSAGE);
+				}
+			}
+		};
+		undoAction.setSelectionManager(selectionManager);
+		return undoAction;
+	}
+
+	public void setSelectionManager(SelectionManager selectionManager) {
+		this.selectionManager = selectionManager;
+		if (undoAction != null)
+			undoAction.setSelectionManager(selectionManager);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/UndoMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/UndoMenuAction.java b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/UndoMenuAction.java
new file mode 100644
index 0000000..7db7c6c
--- /dev/null
+++ b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/UndoMenuAction.java
@@ -0,0 +1,85 @@
+/*
+* 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.edits.impl.menu;
+
+import static javax.swing.JOptionPane.ERROR_MESSAGE;
+import static javax.swing.JOptionPane.showMessageDialog;
+import static org.apache.taverna.workbench.edits.impl.menu.UndoMenuSection.UNDO_SECTION_URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.edits.Edit;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.selection.SelectionManager;
+
+import org.apache.log4j.Logger;
+
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+
+/**
+ * Undo the last {@link Edit} done on the current workflow using the
+ * {@link EditManager}.
+ * 
+ * @author Stian Soiland-Reyes
+ * 
+ */
+public class UndoMenuAction extends AbstractMenuAction {
+	private static Logger logger = Logger.getLogger(UndoMenuAction.class);
+	private final EditManager editManager;
+	private SelectionManager selectionManager;
+	private AbstractUndoAction undoAction;
+
+	public UndoMenuAction(EditManager editManager) {
+		super(UNDO_SECTION_URI, 10);
+		this.editManager = editManager;
+	}
+
+	@SuppressWarnings("serial")
+	@Override
+	protected Action createAction() {
+		undoAction = new AbstractUndoAction("Undo", editManager) {
+			@Override
+			protected boolean isActive(WorkflowBundle workflowBundle) {
+				return editManager.canUndoDataflowEdit(workflowBundle);
+			}
+
+			@Override
+			protected void performUndoOrRedo(WorkflowBundle workflowBundle) {
+				try {
+					editManager.undoDataflowEdit(workflowBundle);
+				} catch (RuntimeException e) {
+					logger.warn("Could not undo for " + workflowBundle, e);
+					showMessageDialog(null, "Could not undo for workflow "
+							+ workflowBundle + ":\n" + e, "Could not undo",
+							ERROR_MESSAGE);
+				}
+			}
+		};
+		undoAction.setSelectionManager(selectionManager);
+		return undoAction;
+	}
+
+	public void setSelectionManager(SelectionManager selectionManager) {
+		this.selectionManager = selectionManager;
+		if (undoAction != null)
+			undoAction.setSelectionManager(selectionManager);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/UndoMenuSection.java
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/UndoMenuSection.java b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/UndoMenuSection.java
new file mode 100644
index 0000000..dfed909
--- /dev/null
+++ b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/menu/UndoMenuSection.java
@@ -0,0 +1,41 @@
+/*
+* 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.edits.impl.menu;
+
+import java.net.URI;
+
+import org.apache.taverna.ui.menu.AbstractMenuSection;
+
+/**
+ * A section of the Edit menu that contains {@link UndoMenuSection undo} and
+ * {@link RedoMenuAction redo}.
+ * 
+ * @author Stian Soiland-Reyes
+ */
+public class UndoMenuSection extends AbstractMenuSection {
+	public static final URI UNDO_SECTION_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/edits#undoSection");
+	public static final URI EDIT_MENU_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#edit");
+
+	public UndoMenuSection() {
+		super(EDIT_MENU_URI, 10, UNDO_SECTION_URI);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/toolbar/EditToolbarSection.java
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/toolbar/EditToolbarSection.java b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/toolbar/EditToolbarSection.java
new file mode 100644
index 0000000..f83bfbc
--- /dev/null
+++ b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/toolbar/EditToolbarSection.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.edits.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 EditToolbarSection extends AbstractMenuSection {
+	public static final URI EDIT_TOOLBAR_SECTION = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#editToolbarSection");
+
+	public EditToolbarSection() {
+		super(DEFAULT_TOOL_BAR, 60, EDIT_TOOLBAR_SECTION);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/toolbar/RedoToolbarAction.java
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/toolbar/RedoToolbarAction.java b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/toolbar/RedoToolbarAction.java
new file mode 100644
index 0000000..d95adb7
--- /dev/null
+++ b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/toolbar/RedoToolbarAction.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.edits.impl.toolbar;
+
+import static org.apache.taverna.workbench.edits.impl.toolbar.EditToolbarSection.EDIT_TOOLBAR_SECTION;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.edits.impl.menu.RedoMenuAction;
+
+public class RedoToolbarAction extends AbstractMenuAction {
+	private static final URI EDIT_TOOLBAR_REDO_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#editToolbarRedo");
+	private final RedoMenuAction redoMenuAction;
+
+	public RedoToolbarAction(RedoMenuAction redoMenuAction) {
+		super(EDIT_TOOLBAR_SECTION, 20, EDIT_TOOLBAR_REDO_URI);
+		this.redoMenuAction = redoMenuAction;
+	}
+
+	@Override
+	protected Action createAction() {
+		return redoMenuAction.getAction();
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/toolbar/UndoToolbarAction.java
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/toolbar/UndoToolbarAction.java b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/toolbar/UndoToolbarAction.java
new file mode 100644
index 0000000..2d9bcae
--- /dev/null
+++ b/taverna-edits-impl/src/main/java/org/apache/taverna/workbench/edits/impl/toolbar/UndoToolbarAction.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.edits.impl.toolbar;
+
+import static org.apache.taverna.workbench.edits.impl.toolbar.EditToolbarSection.EDIT_TOOLBAR_SECTION;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.edits.impl.menu.UndoMenuAction;
+
+public class UndoToolbarAction extends AbstractMenuAction {
+	private static final URI EDIT_TOOLBAR_UNDO_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#editToolbarUndo");
+	private final UndoMenuAction undoMenuAction;
+
+	public UndoToolbarAction(UndoMenuAction undoMenuAction) {
+		super(EDIT_TOOLBAR_SECTION, 10, EDIT_TOOLBAR_UNDO_URI);
+		this.undoMenuAction = undoMenuAction;
+	}
+
+	@Override
+	protected Action createAction() {
+		return undoMenuAction.getAction();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent b/taverna-edits-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
deleted file mode 100644
index 6938308..0000000
--- a/taverna-edits-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
+++ /dev/null
@@ -1,6 +0,0 @@
-net.sf.taverna.t2.workbench.edits.impl.menu.UndoMenuSection
-net.sf.taverna.t2.workbench.edits.impl.menu.UndoMenuAction
-net.sf.taverna.t2.workbench.edits.impl.menu.RedoMenuAction
-net.sf.taverna.t2.workbench.edits.impl.toolbar.EditToolbarSection
-net.sf.taverna.t2.workbench.edits.impl.toolbar.UndoToolbarAction
-net.sf.taverna.t2.workbench.edits.impl.toolbar.RedoToolbarAction

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.edits.EditManager
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.edits.EditManager b/taverna-edits-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.edits.EditManager
deleted file mode 100644
index 92ee088..0000000
--- a/taverna-edits-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.edits.EditManager
+++ /dev/null
@@ -1 +0,0 @@
-net.sf.taverna.t2.workbench.edits.impl.EditManagerImpl

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/main/resources/META-INF/services/org.apache.taverna.ui.menu.MenuComponent
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/main/resources/META-INF/services/org.apache.taverna.ui.menu.MenuComponent b/taverna-edits-impl/src/main/resources/META-INF/services/org.apache.taverna.ui.menu.MenuComponent
new file mode 100644
index 0000000..1019470
--- /dev/null
+++ b/taverna-edits-impl/src/main/resources/META-INF/services/org.apache.taverna.ui.menu.MenuComponent
@@ -0,0 +1,6 @@
+org.apache.taverna.workbench.edits.impl.menu.UndoMenuSection
+org.apache.taverna.workbench.edits.impl.menu.UndoMenuAction
+org.apache.taverna.workbench.edits.impl.menu.RedoMenuAction
+org.apache.taverna.workbench.edits.impl.toolbar.EditToolbarSection
+org.apache.taverna.workbench.edits.impl.toolbar.UndoToolbarAction
+org.apache.taverna.workbench.edits.impl.toolbar.RedoToolbarAction

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.edits.EditManager
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.edits.EditManager b/taverna-edits-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.edits.EditManager
new file mode 100644
index 0000000..bd7f2d8
--- /dev/null
+++ b/taverna-edits-impl/src/main/resources/META-INF/services/org.apache.taverna.workbench.edits.EditManager
@@ -0,0 +1 @@
+org.apache.taverna.workbench.edits.impl.EditManagerImpl

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/main/resources/META-INF/spring/edits-impl-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/main/resources/META-INF/spring/edits-impl-context-osgi.xml b/taverna-edits-impl/src/main/resources/META-INF/spring/edits-impl-context-osgi.xml
index 8eb7041..195b18e 100644
--- a/taverna-edits-impl/src/main/resources/META-INF/spring/edits-impl-context-osgi.xml
+++ b/taverna-edits-impl/src/main/resources/META-INF/spring/edits-impl-context-osgi.xml
@@ -13,8 +13,8 @@
 	<service ref="UndoToolbarAction" auto-export="interfaces" />
 	<service ref="RedoToolbarAction" auto-export="interfaces" />
 
-	<service ref="EditManagerImpl" interface="net.sf.taverna.t2.workbench.edits.EditManager" />
+	<service ref="EditManagerImpl" interface="org.apache.taverna.workbench.edits.EditManager" />
 
-	<reference id="selectionManager" interface="net.sf.taverna.t2.workbench.selection.SelectionManager" cardinality="0..1" />
+	<reference id="selectionManager" interface="org.apache.taverna.workbench.selection.SelectionManager" cardinality="0..1" />
 
 </beans:beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/main/resources/META-INF/spring/edits-impl-context.xml
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/main/resources/META-INF/spring/edits-impl-context.xml b/taverna-edits-impl/src/main/resources/META-INF/spring/edits-impl-context.xml
index 33f0b7b..bba1db8 100644
--- a/taverna-edits-impl/src/main/resources/META-INF/spring/edits-impl-context.xml
+++ b/taverna-edits-impl/src/main/resources/META-INF/spring/edits-impl-context.xml
@@ -3,31 +3,31 @@
 	xsi:schemaLocation="http://www.springframework.org/schema/beans
                       http://www.springframework.org/schema/beans/spring-beans.xsd">
 
-	<bean id="UndoMenuSection" class="net.sf.taverna.t2.workbench.edits.impl.menu.UndoMenuSection" />
-	<bean id="UndoMenuAction" class="net.sf.taverna.t2.workbench.edits.impl.menu.UndoMenuAction">
+	<bean id="UndoMenuSection" class="org.apache.taverna.workbench.edits.impl.menu.UndoMenuSection" />
+	<bean id="UndoMenuAction" class="org.apache.taverna.workbench.edits.impl.menu.UndoMenuAction">
 		<constructor-arg name="editManager">
 			<ref local="EditManagerImpl" />
 		</constructor-arg>
 		<property name="selectionManager" ref="selectionManager" />
 	</bean>
-	<bean id="RedoMenuAction" class="net.sf.taverna.t2.workbench.edits.impl.menu.RedoMenuAction">
+	<bean id="RedoMenuAction" class="org.apache.taverna.workbench.edits.impl.menu.RedoMenuAction">
 		<constructor-arg name="editManager">
 			<ref local="EditManagerImpl" />
 		</constructor-arg>
 		<property name="selectionManager" ref="selectionManager" />
 	</bean>
-	<bean id="EditToolbarSection" class="net.sf.taverna.t2.workbench.edits.impl.toolbar.EditToolbarSection" />
-	<bean id="UndoToolbarAction" class="net.sf.taverna.t2.workbench.edits.impl.toolbar.UndoToolbarAction">
+	<bean id="EditToolbarSection" class="org.apache.taverna.workbench.edits.impl.toolbar.EditToolbarSection" />
+	<bean id="UndoToolbarAction" class="org.apache.taverna.workbench.edits.impl.toolbar.UndoToolbarAction">
 		<constructor-arg>
 			<ref local="UndoMenuAction" />
 		</constructor-arg>
 	</bean>
-	<bean id="RedoToolbarAction" class="net.sf.taverna.t2.workbench.edits.impl.toolbar.RedoToolbarAction">
+	<bean id="RedoToolbarAction" class="org.apache.taverna.workbench.edits.impl.toolbar.RedoToolbarAction">
 		<constructor-arg>
 			<ref local="RedoMenuAction" />
 		</constructor-arg>
 	</bean>
 
-	<bean id="EditManagerImpl" class="net.sf.taverna.t2.workbench.edits.impl.EditManagerImpl" />
+	<bean id="EditManagerImpl" class="org.apache.taverna.workbench.edits.impl.EditManagerImpl" />
 
 </beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/test/java/net/sf/taverna/t2/workbench/edits/impl/TestEditManagerImpl.java
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/test/java/net/sf/taverna/t2/workbench/edits/impl/TestEditManagerImpl.java b/taverna-edits-impl/src/test/java/net/sf/taverna/t2/workbench/edits/impl/TestEditManagerImpl.java
deleted file mode 100644
index 27334b0..0000000
--- a/taverna-edits-impl/src/test/java/net/sf/taverna/t2/workbench/edits/impl/TestEditManagerImpl.java
+++ /dev/null
@@ -1,258 +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.edits.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import org.apache.taverna.lang.observer.Observable;
-import org.apache.taverna.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.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.AddProcessorEdit;
-
-import org.junit.Before;
-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;
-
-public class TestEditManagerImpl {
-
-	private Workflow dataflow;
-
-	private EditManagerObserver editManagerObserver = new EditManagerObserver();
-
-	private Processor processor;
-
-	@Test
-	public void addProcessor() throws Exception {
-		EditManager editManager = new EditManagerImpl();
-		editManager.addObserver(editManagerObserver);
-
-		Edit<Workflow> edit = new AddProcessorEdit(dataflow, processor);
-		assertFalse("Edit was already applied", edit.isApplied());
-		assertTrue("Did already add processor", dataflow.getProcessors()
-				.isEmpty());
-
-		editManager.doDataflowEdit(dataflow.getParent(), edit);
-		assertTrue("Edit was not applied", edit.isApplied());
-		assertEquals("Did not add processor", processor, dataflow.getProcessors().first());
-
-		// Should have received the edit event
-		assertEquals("Incorrect number of events", 1,
-				editManagerObserver.events.size());
-		EditManagerEvent event = editManagerObserver.events.get(0);
-		assertTrue("Event was not a DataflowEditEvent",
-				event instanceof DataflowEditEvent);
-		DataflowEditEvent dataEditEvent = (DataflowEditEvent) event;
-		assertEquals("Event did not have correct workflow", dataflow,
-				dataEditEvent.getDataFlow().getWorkflows().first());
-		assertEquals("Event did not have correct edit", edit, dataEditEvent
-				.getEdit());
-
-	}
-
-	@Test
-	public void undoAddProcessor() throws Exception {
-		EditManager editManager = new EditManagerImpl();
-		editManager.addObserver(editManagerObserver);
-
-		Edit<Workflow> edit = new AddProcessorEdit(dataflow, processor);
-		editManager.doDataflowEdit(dataflow.getParent(), edit);
-
-		assertFalse("Did not add processor", dataflow.getProcessors().isEmpty());
-		editManager.undoDataflowEdit(dataflow.getParent());
-		assertTrue("Did not undo add processor", dataflow.getProcessors()
-				.isEmpty());
-
-		// Should have received the undo event
-		assertEquals("Incorrect number of events", 2,
-				editManagerObserver.events.size());
-		EditManagerEvent event = editManagerObserver.events.get(1);
-		assertTrue("Event was not a DataflowEditEvent",
-				event instanceof DataFlowUndoEvent);
-		DataFlowUndoEvent dataEditEvent = (DataFlowUndoEvent) event;
-		assertEquals("Event did not have correct workflow", dataflow,
-				dataEditEvent.getDataFlow().getWorkflows().first());
-		assertEquals("Event did not have correct edit", edit, dataEditEvent
-				.getEdit());
-		assertFalse("Edit was still applied", edit.isApplied());
-	}
-
-	@Test
-	public void multipleUndoesRedoes() throws Exception {
-		EditManager editManager = new EditManagerImpl();
-		editManager.addObserver(editManagerObserver);
-
-		Workflow dataflowA = createDataflow();
-		Workflow dataflowB = createDataflow();
-		Workflow dataflowC = createDataflow();
-
-		Processor processorA1 = createProcessor();
-		Processor processorA2 = createProcessor();
-		Processor processorA3 = createProcessor();
-		Processor processorB1 = createProcessor();
-		Processor processorC1 = createProcessor();
-
-		Edit<Workflow> edit = new AddProcessorEdit(dataflowA, processorA1);
-		editManager.doDataflowEdit(dataflowA.getParent(), edit);
-
-		edit = new AddProcessorEdit(dataflowB, processorB1);
-		editManager.doDataflowEdit(dataflowB.getParent(), edit);
-
-		edit = new AddProcessorEdit(dataflowA, processorA2);
-		editManager.doDataflowEdit(dataflowA.getParent(), edit);
-
-		edit = new AddProcessorEdit(dataflowC, processorC1);
-		editManager.doDataflowEdit(dataflowC.getParent(), edit);
-
-		edit = new AddProcessorEdit(dataflowA, processorA3);
-		editManager.doDataflowEdit(dataflowA.getParent(), edit);
-
-
-
-		assertFalse("Did not add processors", dataflowA.getProcessors().isEmpty());
-		assertEquals(3, dataflowA.getProcessors().size());
-		editManager.undoDataflowEdit(dataflowA.getParent());
-		assertEquals(2, dataflowA.getProcessors().size());
-		editManager.undoDataflowEdit(dataflowA.getParent());
-		assertEquals(1, dataflowA.getProcessors().size());
-		editManager.undoDataflowEdit(dataflowA.getParent());
-		assertEquals(0, dataflowA.getProcessors().size());
-
-		assertEquals(1, dataflowB.getProcessors().size());
-		assertEquals(1, dataflowC.getProcessors().size());
-
-		assertTrue(editManager.canUndoDataflowEdit(dataflowC.getParent()));
-		editManager.undoDataflowEdit(dataflowC.getParent());
-		assertFalse(editManager.canUndoDataflowEdit(dataflowC.getParent()));
-		editManager.undoDataflowEdit(dataflowC.getParent()); // extra one
-		assertFalse(editManager.canUndoDataflowEdit(dataflowC.getParent()));
-
-
-		assertEquals(1, dataflowB.getProcessors().size());
-		assertEquals(0, dataflowC.getProcessors().size());
-
-		editManager.undoDataflowEdit(dataflowB.getParent());
-		assertEquals(0, dataflowA.getProcessors().size());
-		assertEquals(0, dataflowB.getProcessors().size());
-		assertEquals(0, dataflowC.getProcessors().size());
-
-		editManager.redoDataflowEdit(dataflowA.getParent());
-		assertEquals(1, dataflowA.getProcessors().size());
-
-		editManager.redoDataflowEdit(dataflowA.getParent());
-		assertEquals(2, dataflowA.getProcessors().size());
-
-		editManager.redoDataflowEdit(dataflowA.getParent());
-		assertEquals(3, dataflowA.getProcessors().size());
-
-		// does not affect it
-		editManager.redoDataflowEdit(dataflowA.getParent());
-		assertEquals(3, dataflowA.getProcessors().size());
-		assertEquals(0, dataflowB.getProcessors().size());
-		assertEquals(0, dataflowC.getProcessors().size());
-	}
-
-	@Test
-	public void emptyUndoDoesNotFail() throws Exception {
-		EditManager editManager = new EditManagerImpl();
-		editManager.addObserver(editManagerObserver);
-		editManager.undoDataflowEdit(dataflow.getParent());
-	}
-
-	@Test
-	public void extraUndoesDoesNotFail() throws Exception {
-		EditManager editManager = new EditManagerImpl();
-		editManager.addObserver(editManagerObserver);
-
-		Edit<Workflow> edit = new AddProcessorEdit(dataflow, processor);
-		editManager.doDataflowEdit(dataflow.getParent(), edit);
-
-		assertFalse("Did not add processor", dataflow.getProcessors().isEmpty());
-		editManager.undoDataflowEdit(dataflow.getParent());
-		assertTrue("Did not undo add processor", dataflow.getProcessors()
-				.isEmpty());
-		editManager.undoDataflowEdit(dataflow.getParent());
-	}
-
-	@Before
-	public void makeDataflow() {
-		dataflow = createDataflow();
-	}
-
-	protected Workflow createDataflow() {
-		WorkflowBundle workflowBundle = new WorkflowBundle();
-		Workflow workflow = new Workflow();
-		workflow.setParent(workflowBundle);
-		return workflow;
-	}
-
-	protected Processor createProcessor() {
-		Processor processor = new Processor();
-		processor.setName("proc-" + UUID.randomUUID());
-		return processor;
-	}
-
-	@Before
-	public void makeProcessor() {
-		processor = createProcessor();
-	}
-
-	private class EditManagerObserver implements Observer<EditManagerEvent> {
-
-		public List<EditManagerEvent> events = new ArrayList<>();
-
-		@Override
-		public void notify(Observable<EditManagerEvent> sender,
-				EditManagerEvent message) throws Exception {
-			events.add(message);
-			if (message instanceof DataflowEditEvent) {
-				DataflowEditEvent dataflowEdit = (DataflowEditEvent) message;
-				assertTrue("Edit was not applied on edit event", dataflowEdit
-						.getEdit().isApplied());
-			} else if (message instanceof DataFlowUndoEvent) {
-				DataFlowUndoEvent dataflowUndo = (DataFlowUndoEvent) message;
-				assertFalse("Edit was applied on undo event", dataflowUndo
-						.getEdit().isApplied());
-			} else if (message instanceof DataFlowRedoEvent) {
-				DataFlowRedoEvent dataflowEdit = (DataFlowRedoEvent) message;
-				assertTrue("Edit was not applied on edit event", dataflowEdit
-						.getEdit().isApplied());
-			} else {
-				fail("Unknown event: " + message);
-			}
-		}
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-edits-impl/src/test/java/org/apache/taverna/workbench/edits/impl/TestEditManagerImpl.java
----------------------------------------------------------------------
diff --git a/taverna-edits-impl/src/test/java/org/apache/taverna/workbench/edits/impl/TestEditManagerImpl.java b/taverna-edits-impl/src/test/java/org/apache/taverna/workbench/edits/impl/TestEditManagerImpl.java
new file mode 100644
index 0000000..aed29cb
--- /dev/null
+++ b/taverna-edits-impl/src/test/java/org/apache/taverna/workbench/edits/impl/TestEditManagerImpl.java
@@ -0,0 +1,257 @@
+/*
+* 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.edits.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+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.EditManager.DataFlowRedoEvent;
+import org.apache.taverna.workbench.edits.EditManager.DataFlowUndoEvent;
+import org.apache.taverna.workbench.edits.EditManager.DataflowEditEvent;
+import org.apache.taverna.workbench.edits.EditManager.EditManagerEvent;
+import org.apache.taverna.workflow.edits.AddProcessorEdit;
+
+import org.junit.Before;
+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;
+
+public class TestEditManagerImpl {
+
+	private Workflow dataflow;
+
+	private EditManagerObserver editManagerObserver = new EditManagerObserver();
+
+	private Processor processor;
+
+	@Test
+	public void addProcessor() throws Exception {
+		EditManager editManager = new EditManagerImpl();
+		editManager.addObserver(editManagerObserver);
+
+		Edit<Workflow> edit = new AddProcessorEdit(dataflow, processor);
+		assertFalse("Edit was already applied", edit.isApplied());
+		assertTrue("Did already add processor", dataflow.getProcessors()
+				.isEmpty());
+
+		editManager.doDataflowEdit(dataflow.getParent(), edit);
+		assertTrue("Edit was not applied", edit.isApplied());
+		assertEquals("Did not add processor", processor, dataflow.getProcessors().first());
+
+		// Should have received the edit event
+		assertEquals("Incorrect number of events", 1,
+				editManagerObserver.events.size());
+		EditManagerEvent event = editManagerObserver.events.get(0);
+		assertTrue("Event was not a DataflowEditEvent",
+				event instanceof DataflowEditEvent);
+		DataflowEditEvent dataEditEvent = (DataflowEditEvent) event;
+		assertEquals("Event did not have correct workflow", dataflow,
+				dataEditEvent.getDataFlow().getWorkflows().first());
+		assertEquals("Event did not have correct edit", edit, dataEditEvent
+				.getEdit());
+
+	}
+
+	@Test
+	public void undoAddProcessor() throws Exception {
+		EditManager editManager = new EditManagerImpl();
+		editManager.addObserver(editManagerObserver);
+
+		Edit<Workflow> edit = new AddProcessorEdit(dataflow, processor);
+		editManager.doDataflowEdit(dataflow.getParent(), edit);
+
+		assertFalse("Did not add processor", dataflow.getProcessors().isEmpty());
+		editManager.undoDataflowEdit(dataflow.getParent());
+		assertTrue("Did not undo add processor", dataflow.getProcessors()
+				.isEmpty());
+
+		// Should have received the undo event
+		assertEquals("Incorrect number of events", 2,
+				editManagerObserver.events.size());
+		EditManagerEvent event = editManagerObserver.events.get(1);
+		assertTrue("Event was not a DataflowEditEvent",
+				event instanceof DataFlowUndoEvent);
+		DataFlowUndoEvent dataEditEvent = (DataFlowUndoEvent) event;
+		assertEquals("Event did not have correct workflow", dataflow,
+				dataEditEvent.getDataFlow().getWorkflows().first());
+		assertEquals("Event did not have correct edit", edit, dataEditEvent
+				.getEdit());
+		assertFalse("Edit was still applied", edit.isApplied());
+	}
+
+	@Test
+	public void multipleUndoesRedoes() throws Exception {
+		EditManager editManager = new EditManagerImpl();
+		editManager.addObserver(editManagerObserver);
+
+		Workflow dataflowA = createDataflow();
+		Workflow dataflowB = createDataflow();
+		Workflow dataflowC = createDataflow();
+
+		Processor processorA1 = createProcessor();
+		Processor processorA2 = createProcessor();
+		Processor processorA3 = createProcessor();
+		Processor processorB1 = createProcessor();
+		Processor processorC1 = createProcessor();
+
+		Edit<Workflow> edit = new AddProcessorEdit(dataflowA, processorA1);
+		editManager.doDataflowEdit(dataflowA.getParent(), edit);
+
+		edit = new AddProcessorEdit(dataflowB, processorB1);
+		editManager.doDataflowEdit(dataflowB.getParent(), edit);
+
+		edit = new AddProcessorEdit(dataflowA, processorA2);
+		editManager.doDataflowEdit(dataflowA.getParent(), edit);
+
+		edit = new AddProcessorEdit(dataflowC, processorC1);
+		editManager.doDataflowEdit(dataflowC.getParent(), edit);
+
+		edit = new AddProcessorEdit(dataflowA, processorA3);
+		editManager.doDataflowEdit(dataflowA.getParent(), edit);
+
+
+
+		assertFalse("Did not add processors", dataflowA.getProcessors().isEmpty());
+		assertEquals(3, dataflowA.getProcessors().size());
+		editManager.undoDataflowEdit(dataflowA.getParent());
+		assertEquals(2, dataflowA.getProcessors().size());
+		editManager.undoDataflowEdit(dataflowA.getParent());
+		assertEquals(1, dataflowA.getProcessors().size());
+		editManager.undoDataflowEdit(dataflowA.getParent());
+		assertEquals(0, dataflowA.getProcessors().size());
+
+		assertEquals(1, dataflowB.getProcessors().size());
+		assertEquals(1, dataflowC.getProcessors().size());
+
+		assertTrue(editManager.canUndoDataflowEdit(dataflowC.getParent()));
+		editManager.undoDataflowEdit(dataflowC.getParent());
+		assertFalse(editManager.canUndoDataflowEdit(dataflowC.getParent()));
+		editManager.undoDataflowEdit(dataflowC.getParent()); // extra one
+		assertFalse(editManager.canUndoDataflowEdit(dataflowC.getParent()));
+
+
+		assertEquals(1, dataflowB.getProcessors().size());
+		assertEquals(0, dataflowC.getProcessors().size());
+
+		editManager.undoDataflowEdit(dataflowB.getParent());
+		assertEquals(0, dataflowA.getProcessors().size());
+		assertEquals(0, dataflowB.getProcessors().size());
+		assertEquals(0, dataflowC.getProcessors().size());
+
+		editManager.redoDataflowEdit(dataflowA.getParent());
+		assertEquals(1, dataflowA.getProcessors().size());
+
+		editManager.redoDataflowEdit(dataflowA.getParent());
+		assertEquals(2, dataflowA.getProcessors().size());
+
+		editManager.redoDataflowEdit(dataflowA.getParent());
+		assertEquals(3, dataflowA.getProcessors().size());
+
+		// does not affect it
+		editManager.redoDataflowEdit(dataflowA.getParent());
+		assertEquals(3, dataflowA.getProcessors().size());
+		assertEquals(0, dataflowB.getProcessors().size());
+		assertEquals(0, dataflowC.getProcessors().size());
+	}
+
+	@Test
+	public void emptyUndoDoesNotFail() throws Exception {
+		EditManager editManager = new EditManagerImpl();
+		editManager.addObserver(editManagerObserver);
+		editManager.undoDataflowEdit(dataflow.getParent());
+	}
+
+	@Test
+	public void extraUndoesDoesNotFail() throws Exception {
+		EditManager editManager = new EditManagerImpl();
+		editManager.addObserver(editManagerObserver);
+
+		Edit<Workflow> edit = new AddProcessorEdit(dataflow, processor);
+		editManager.doDataflowEdit(dataflow.getParent(), edit);
+
+		assertFalse("Did not add processor", dataflow.getProcessors().isEmpty());
+		editManager.undoDataflowEdit(dataflow.getParent());
+		assertTrue("Did not undo add processor", dataflow.getProcessors()
+				.isEmpty());
+		editManager.undoDataflowEdit(dataflow.getParent());
+	}
+
+	@Before
+	public void makeDataflow() {
+		dataflow = createDataflow();
+	}
+
+	protected Workflow createDataflow() {
+		WorkflowBundle workflowBundle = new WorkflowBundle();
+		Workflow workflow = new Workflow();
+		workflow.setParent(workflowBundle);
+		return workflow;
+	}
+
+	protected Processor createProcessor() {
+		Processor processor = new Processor();
+		processor.setName("proc-" + UUID.randomUUID());
+		return processor;
+	}
+
+	@Before
+	public void makeProcessor() {
+		processor = createProcessor();
+	}
+
+	private class EditManagerObserver implements Observer<EditManagerEvent> {
+
+		public List<EditManagerEvent> events = new ArrayList<>();
+
+		@Override
+		public void notify(Observable<EditManagerEvent> sender,
+				EditManagerEvent message) throws Exception {
+			events.add(message);
+			if (message instanceof DataflowEditEvent) {
+				DataflowEditEvent dataflowEdit = (DataflowEditEvent) message;
+				assertTrue("Edit was not applied on edit event", dataflowEdit
+						.getEdit().isApplied());
+			} else if (message instanceof DataFlowUndoEvent) {
+				DataFlowUndoEvent dataflowUndo = (DataFlowUndoEvent) message;
+				assertFalse("Edit was applied on undo event", dataflowUndo
+						.getEdit().isApplied());
+			} else if (message instanceof DataFlowRedoEvent) {
+				DataFlowRedoEvent dataflowEdit = (DataFlowRedoEvent) message;
+				assertTrue("Edit was not applied on edit event", dataflowEdit
+						.getEdit().isApplied());
+			} else {
+				fail("Unknown event: " + message);
+			}
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-file-api/src/main/java/net/sf/taverna/t2/workbench/file/AbstractDataflowPersistenceHandler.java
----------------------------------------------------------------------
diff --git a/taverna-file-api/src/main/java/net/sf/taverna/t2/workbench/file/AbstractDataflowPersistenceHandler.java b/taverna-file-api/src/main/java/net/sf/taverna/t2/workbench/file/AbstractDataflowPersistenceHandler.java
deleted file mode 100644
index a5e606b..0000000
--- a/taverna-file-api/src/main/java/net/sf/taverna/t2/workbench/file/AbstractDataflowPersistenceHandler.java
+++ /dev/null
@@ -1,69 +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;
-
-import java.util.Collections;
-import java.util.List;
-
-import net.sf.taverna.t2.workbench.file.exceptions.OpenException;
-import net.sf.taverna.t2.workbench.file.exceptions.SaveException;
-import org.apache.taverna.scufl2.api.container.WorkflowBundle;
-
-public abstract class AbstractDataflowPersistenceHandler implements
-		DataflowPersistenceHandler {
-	@Override
-	public List<FileType> getOpenFileTypes() {
-		return Collections.emptyList();
-	}
-
-	@Override
-	public List<FileType> getSaveFileTypes() {
-		return Collections.emptyList();
-	}
-
-	@Override
-	public List<Class<?>> getOpenSourceTypes() {
-		return Collections.emptyList();
-	}
-
-	@Override
-	public List<Class<?>> getSaveDestinationTypes() {
-		return Collections.emptyList();
-	}
-
-	@Override
-	public DataflowInfo openDataflow(FileType fileType, Object source)
-			throws OpenException {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public DataflowInfo saveDataflow(WorkflowBundle workflowBundle, FileType fileType,
-			Object destination) throws SaveException {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public boolean wouldOverwriteDataflow(WorkflowBundle workflowBundle, FileType fileType,
-			Object destination, DataflowInfo lastDataflowInfo) {
-		throw new UnsupportedOperationException();
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-file-api/src/main/java/net/sf/taverna/t2/workbench/file/DataflowInfo.java
----------------------------------------------------------------------
diff --git a/taverna-file-api/src/main/java/net/sf/taverna/t2/workbench/file/DataflowInfo.java b/taverna-file-api/src/main/java/net/sf/taverna/t2/workbench/file/DataflowInfo.java
deleted file mode 100644
index 469d13b..0000000
--- a/taverna-file-api/src/main/java/net/sf/taverna/t2/workbench/file/DataflowInfo.java
+++ /dev/null
@@ -1,108 +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;
-
-import java.util.Date;
-
-import org.apache.taverna.scufl2.api.container.WorkflowBundle;
-
-/**
- * Information about a WorkflowBundle that has been opened by the
- * {@link FileManager}.
- * <p>
- * This class, or a subclass of it, is used by
- * {@link DataflowPersistenceHandler}s to keep information about where a
- * {@link WorkflowBundle} came from or where it was saved to.
- * 
- * @author Stian Soiland-Reyes
- */
-public class DataflowInfo {
-	private final FileType fileType;
-	private final WorkflowBundle worflowBundle;
-	private final Date lastModified;
-	private final Object canonicalSource;
-
-	public DataflowInfo(FileType fileType, Object canonicalSource,
-			WorkflowBundle worflowBundle, Date lastModified) {
-		this.fileType = fileType;
-		this.canonicalSource = canonicalSource;
-		this.worflowBundle = worflowBundle;
-		this.lastModified = lastModified;
-	}
-
-	public DataflowInfo(FileType fileType, Object canonicalSource,
-			WorkflowBundle worflowBundle) {
-		this(fileType, canonicalSource, worflowBundle, null);
-	}
-
-	/**
-	 * Return the canonical source of where the WorkflowBundle was opened from
-	 * or saved to.
-	 * <p>
-	 * This is not necessarily the source provided to
-	 * {@link FileManager#openDataflow(FileType, Object)} or
-	 * {@link FileManager#saveDataflow(WorkflowBundle, FileType, Object, boolean)}
-	 * , but it's canonical version.
-	 * <p>
-	 * For instance, if a WorkflowBundle was opened from a
-	 * File("relative/something.wfbundle) this canonical source would resolve
-	 * the relative path.
-	 * 
-	 * @return
-	 */
-	public Object getCanonicalSource() {
-		return canonicalSource;
-	}
-
-	/**
-	 * Return the WorkflowBundle that is open.
-	 * 
-	 * @return The open WorkflowBundle
-	 */
-	public WorkflowBundle getDataflow() {
-		return worflowBundle;
-	}
-
-	/**
-	 * Get the last modified {@link Date} of the source at the time when it was
-	 * opened/saved.
-	 * <p>
-	 * It is important that this value is checked on creation time, and not on
-	 * demand.
-	 * 
-	 * @return The {@link Date} of the source/destination's last modified
-	 *         timestamp, or <code>null</code> if unknown.
-	 */
-	public Date getLastModified() {
-		return lastModified;
-	}
-
-	/**
-	 * The {@link FileType} of this {@link WorkflowBundle} serialisation used
-	 * for opening/saving.
-	 * 
-	 * @return The {@link FileType}, for instance
-	 *         {@link net.sf.taverna.t2.workbench.file.impl.WorkflowBundleFileType}
-	 */
-	public FileType getFileType() {
-		return fileType;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-file-api/src/main/java/net/sf/taverna/t2/workbench/file/DataflowPersistenceHandler.java
----------------------------------------------------------------------
diff --git a/taverna-file-api/src/main/java/net/sf/taverna/t2/workbench/file/DataflowPersistenceHandler.java b/taverna-file-api/src/main/java/net/sf/taverna/t2/workbench/file/DataflowPersistenceHandler.java
deleted file mode 100644
index 4b9234a..0000000
--- a/taverna-file-api/src/main/java/net/sf/taverna/t2/workbench/file/DataflowPersistenceHandler.java
+++ /dev/null
@@ -1,152 +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;
-
-import java.io.File;
-import java.net.URL;
-import java.util.Collection;
-
-import net.sf.taverna.t2.workbench.file.exceptions.OpenException;
-import net.sf.taverna.t2.workbench.file.exceptions.SaveException;
-import org.apache.taverna.scufl2.api.container.WorkflowBundle;
-
-/**
- * A handler for opening or saving {@link WorkflowBundle} from the
- * {@link FileManager}.
- * 
- * @author Stian Soiland-Reyes
- */
-public interface DataflowPersistenceHandler {
-	/**
-	 * A collection of supported file types for
-	 * {@link #openDataflow(FileType, Object)}, or an empty collection if
-	 * opening is not supported by this handler.
-	 * 
-	 * @return A collection of supported {@link FileType}s for opening.
-	 */
-	Collection<FileType> getOpenFileTypes();
-
-	/**
-	 * A collection of supported source classes for
-	 * {@link #openDataflow(FileType, Object)}, or an empty collection if
-	 * opening is not supported by this handler.
-	 * <p>
-	 * For example, a handler that supports sources opened from a {@link File}
-	 * and {@link URL} could return
-	 * <code>Arrays.asList(File.class, URL.class)</code>
-	 * 
-	 * @return A collection of supported {@link Class}es of the open source
-	 *         types.
-	 */
-	Collection<Class<?>> getOpenSourceTypes();
-
-	/**
-	 * A collection of supported destination classes for
-	 * {@link #saveDataflow(Dataflow, FileType, Object)}, or an empty collection
-	 * if saving is not supported by this handler.
-	 * <p>
-	 * For example, a handler that supports saving to destinations that are
-	 * instances of a {@link File} could return
-	 * <code>Arrays.asList(File.class)</code>
-	 * 
-	 * @return A collection of supported {{@link Class}es of the save
-	 *         destination types.
-	 */
-	Collection<Class<?>> getSaveDestinationTypes();
-
-	/**
-	 * A collection of supported file types for
-	 * {@link #saveDataflow(WorkflowBundle, FileType, Object)}, or an empty
-	 * collection if saving is not supported by this handler.
-	 * 
-	 * @return A collection of supported {@link FileType}s for saving.
-	 */
-	Collection<FileType> getSaveFileTypes();
-
-	/**
-	 * Open a dataflow from a source containing a dataflow of the given
-	 * {@link FileType}.
-	 * <p>
-	 * The {@link FileType} will be equal to one of the types from
-	 * {@link #getOpenFileTypes()}, and the source class will be one that is
-	 * assignable to one of the classes from {@link #getOpenSourceTypes()}.
-	 * 
-	 * @param fileType
-	 *            {@link FileType} determining which serialisation method has
-	 *            been used
-	 * @param source
-	 *            Source for reading the WorkflowBundle
-	 * @return {@link DataflowInfo} describing the opened WorkflowBundle,
-	 *         including the WorkflowBundle itself
-	 * @throws OpenException
-	 *             If the WorkflowBundle could not be read, parsed or opened for
-	 *             any reason.
-	 */
-	DataflowInfo openDataflow(FileType fileType, Object source)
-			throws OpenException;
-
-	/**
-	 * Save a WorkflowBundle to a destination of the given {@link FileType}.
-	 * <p>
-	 * The {@link FileType} will be equal to one of the types from
-	 * {@link #getSaveFileTypes()}, and the destination class will be one that
-	 * is assignable to one of the classes from
-	 * {@link #getSaveDestinationTypes()}.
-	 * 
-	 * @param dataflow
-	 *            {@link WorkflowBundle} to be saved
-	 * @param fileType
-	 *            {@link FileType} determining which serialisation method to use
-	 * @param destination
-	 *            Destination for writing the WorkflowBundle
-	 * @return {@link DataflowInfo} describing the saved WorkflowBundle,
-	 *         including the WorkflowBundle itself
-	 * @throws OpenException
-	 *             If the WorkflowBundle could not be read, parsed or opened for
-	 *             any reason.
-	 */
-	DataflowInfo saveDataflow(WorkflowBundle dataflow, FileType fileType,
-			Object destination) throws SaveException;
-
-	/**
-	 * Return <code>true</code> if a call to
-	 * {@link #saveDataflow(WorkflowBundle, FileType, Object)} would overwrite
-	 * the destination, and the destination is different from last
-	 * {@link #openDataflow(FileType, Object)} or
-	 * {@link #saveDataflow(WorkflowBundle, FileType, Object)} of the given
-	 * dataflow.
-	 * 
-	 * @param dataflow
-	 *            {@link WorkflowBundle} that is to be saved
-	 * @param fileType
-	 *            {@link FileType} for saving WorkflowBundle
-	 * @param destination
-	 *            destination for writing WorkflowBundle
-	 * @param lastDataflowInfo
-	 *            last provided {@link DataflowInfo} returned by
-	 *            {@link #openDataflow(FileType, Object)} or
-	 *            {@link #saveDataflow(WorkflowBundle, FileType, Object)}. (but
-	 *            not necessarily from this handler)
-	 * @return <code>true</code> if the save would overwrite
-	 */
-	boolean wouldOverwriteDataflow(WorkflowBundle dataflow, FileType fileType,
-			Object destination, DataflowInfo lastDataflowInfo);
-}