You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/03/20 15:22:43 UTC

[29/51] [abbrv] [partial] incubator-taverna-workbench git commit: taverna-workbench-* -> taverna-*

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-model/src/test/java/net/sf/taverna/t2/workbench/models/graph/GraphElementTest.java
----------------------------------------------------------------------
diff --git a/taverna-graph-model/src/test/java/net/sf/taverna/t2/workbench/models/graph/GraphElementTest.java b/taverna-graph-model/src/test/java/net/sf/taverna/t2/workbench/models/graph/GraphElementTest.java
new file mode 100644
index 0000000..8d6b7f8
--- /dev/null
+++ b/taverna-graph-model/src/test/java/net/sf/taverna/t2/workbench/models/graph/GraphElementTest.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * 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.models.graph;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.awt.Color;
+
+import net.sf.taverna.t2.workbench.models.graph.GraphElement.LineStyle;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class GraphElementTest {
+
+	private GraphElement element;
+
+	private String id;
+
+	private String label;
+
+	private LineStyle lineStyle;
+
+	private Color color;
+
+	private Color fillColor;
+
+	private GraphElement parent;
+
+	private GraphController graphController;
+
+	@Before
+	public void setUp() throws Exception {
+		element = new GraphElement(graphController) {};
+		id = "element-id";
+		label = "element-label";
+		lineStyle = LineStyle.NONE;
+		color = Color.BLUE;
+		fillColor = Color.GREEN;
+		parent = new GraphNode(graphController);
+		element.setId(id);
+		element.setLabel(label);
+		element.setLineStyle(lineStyle);
+		element.setColor(color);
+		element.setFillColor(fillColor);
+		element.setParent(parent);
+	}
+
+	@Test
+	public void testGetParent() {
+		assertEquals(parent, element.getParent());
+	}
+
+	@Test
+	public void testSetParent() {
+		GraphNode newParent = new GraphNode(graphController);
+		element.setParent(newParent);
+		assertEquals(newParent, element.getParent());
+		element.setParent(null);
+		assertNull(element.getParent());
+	}
+
+	@Test
+	public void testGetLabel() {
+		assertEquals(label, element.getLabel());
+	}
+
+	@Test
+	public void testSetLabel() {
+		element.setLabel("new-label");
+		assertEquals("new-label", element.getLabel());
+		element.setLabel(null);
+		assertNull(element.getLabel());
+	}
+
+	@Test
+	public void testGetId() {
+		assertEquals(id, element.getId());
+	}
+
+	@Test
+	public void testSetId() {
+		element.setId("new-id");
+		assertEquals("new-id", element.getId());
+		element.setId(null);
+		assertNull(element.getId());
+	}
+
+	@Test
+	public void testGetColor() {
+		assertEquals(color, element.getColor());
+	}
+
+	@Test
+	public void testSetColor() {
+		element.setColor(Color.RED);
+		assertEquals(Color.RED, element.getColor());
+		element.setColor(null);
+		assertNull(element.getColor());
+	}
+
+	@Test
+	public void testGetFillColor() {
+		assertEquals(fillColor, element.getFillColor());
+	}
+
+	@Test
+	public void testSetFillColor() {
+		element.setFillColor(Color.RED);
+		assertEquals(Color.RED, element.getFillColor());
+		element.setFillColor(null);
+		assertNull(element.getFillColor());
+	}
+
+	@Test
+	public void testGetLineStyle() {
+		assertEquals(lineStyle, element.getLineStyle());
+	}
+
+	@Test
+	public void testSetLineStyle() {
+		element.setLineStyle(LineStyle.DOTTED);
+		assertEquals(LineStyle.DOTTED, element.getLineStyle());
+		element.setLineStyle(null);
+		assertNull(element.getLineStyle());
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-model/src/test/java/net/sf/taverna/t2/workbench/models/graph/GraphNodeTest.java
----------------------------------------------------------------------
diff --git a/taverna-graph-model/src/test/java/net/sf/taverna/t2/workbench/models/graph/GraphNodeTest.java b/taverna-graph-model/src/test/java/net/sf/taverna/t2/workbench/models/graph/GraphNodeTest.java
new file mode 100644
index 0000000..c5bcd6c
--- /dev/null
+++ b/taverna-graph-model/src/test/java/net/sf/taverna/t2/workbench/models/graph/GraphNodeTest.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * 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.models.graph;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.awt.Dimension;
+
+import net.sf.taverna.t2.workbench.models.graph.GraphShapeElement.Shape;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class GraphNodeTest {
+
+	private GraphNode node;
+
+	private Shape shape;
+
+	private Dimension size;
+
+	private Graph graph;
+
+	private boolean expanded;
+
+	private GraphController graphController;
+
+	@Before
+	public void setUp() throws Exception {
+		shape = Shape.HOUSE;
+		size = new Dimension(1, 2);
+		graph = new Graph(graphController);
+		expanded = false;
+		node = new GraphNode(graphController);
+		node.setShape(shape);
+		node.setSize(size);
+		node.setGraph(graph);
+		node.setExpanded(expanded);
+	}
+
+	@Test
+	public void testNode() {
+		assertNotNull(new GraphNode(graphController));
+	}
+
+	@Test
+	public void testAddSinkNode() {
+		GraphNode newNode = new GraphNode(graphController);
+		node.addSinkNode(newNode);
+		assertEquals(1, node.getSinkNodes().size());
+		assertTrue(node.getSinkNodes().contains(newNode));
+		assertEquals(node, newNode.getParent());
+	}
+
+	@Test
+	public void testAddSourceNode() {
+		GraphNode newNode = new GraphNode(graphController);
+		node.addSourceNode(newNode);
+		assertEquals(1, node.getSourceNodes().size());
+		assertTrue(node.getSourceNodes().contains(newNode));
+		assertEquals(node, newNode.getParent());
+	}
+
+	@Test
+	public void testGetGraph() {
+		assertEquals(graph, node.getGraph());
+	}
+
+	@Test
+	public void testGetHeight() {
+		assertEquals(size.height, node.getHeight(), 0);
+	}
+
+	@Test
+	public void testGetShape() {
+		assertEquals(shape, node.getShape());
+	}
+
+	@Test
+	public void testGetSinkNodes() {
+		assertNotNull(node.getSinkNodes());
+		assertEquals(0, node.getSinkNodes().size());
+	}
+
+	@Test
+	public void testGetSize() {
+		assertEquals(size, node.getSize());
+	}
+
+	@Test
+	public void testGetSourceNodes() {
+		assertNotNull(node.getSourceNodes());
+		assertEquals(0, node.getSourceNodes().size());
+	}
+
+	@Test
+	public void testGetWidth() {
+		assertEquals(size.width, node.getWidth(), 0);
+	}
+
+	@Test
+	public void testIsExpanded() {
+		assertEquals(expanded, node.isExpanded());
+	}
+
+	@Test
+	public void testRemoveSinkNode() {
+		GraphNode newNode = new GraphNode(graphController);
+		assertFalse(node.removeSinkNode(newNode));
+		node.addSinkNode(newNode);
+		assertTrue(node.removeSinkNode(newNode));
+		assertFalse(node.getSinkNodes().contains(newNode));
+	}
+
+	@Test
+	public void testRemoveSourceNode() {
+		GraphNode newNode = new GraphNode(graphController);
+		assertFalse(node.removeSourceNode(newNode));
+		node.addSourceNode(newNode);
+		assertTrue(node.removeSourceNode(newNode));
+		assertFalse(node.getSourceNodes().contains(newNode));
+	}
+
+	@Test
+	public void testSetExpanded() {
+		node.setExpanded(true);
+		assertEquals(true, node.isExpanded());
+		node.setExpanded(false);
+		assertEquals(false, node.isExpanded());
+	}
+
+	@Test
+	public void testSetGraph() {
+		Graph newGraph = new Graph(graphController);
+		node.setGraph(newGraph);
+		assertEquals(newGraph, node.getGraph());
+		node.setGraph(null);
+		assertNull(node.getGraph());
+	}
+
+	@Test
+	public void testSetShape() {
+		node.setShape(Shape.INVTRIANGLE);
+		assertEquals(Shape.INVTRIANGLE, node.getShape());
+		node.setShape(Shape.TRIANGLE);
+		assertEquals(Shape.TRIANGLE, node.getShape());
+	}
+
+	@Test
+	public void testSetSize() {
+		node.setSize(new Dimension(23, 6));
+		assertEquals(new Dimension(23, 6), node.getSize());
+		node.setSize(new Dimension(14, 4));
+		assertEquals(new Dimension(14, 4), node.getSize());
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-model/src/test/java/net/sf/taverna/t2/workbench/models/graph/GraphTest.java
----------------------------------------------------------------------
diff --git a/taverna-graph-model/src/test/java/net/sf/taverna/t2/workbench/models/graph/GraphTest.java b/taverna-graph-model/src/test/java/net/sf/taverna/t2/workbench/models/graph/GraphTest.java
new file mode 100644
index 0000000..44a5aaf
--- /dev/null
+++ b/taverna-graph-model/src/test/java/net/sf/taverna/t2/workbench/models/graph/GraphTest.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * 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.models.graph;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import net.sf.taverna.t2.workbench.models.graph.GraphEdge;
+import net.sf.taverna.t2.workbench.models.graph.Graph;
+import net.sf.taverna.t2.workbench.models.graph.GraphNode;
+import net.sf.taverna.t2.workbench.models.graph.Graph.Alignment;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class GraphTest {
+
+	private Graph graph;
+
+	private Alignment alignment;
+
+	private GraphController graphController;
+
+	@Before
+	public void setUp() throws Exception {
+		alignment = Alignment.VERTICAL;
+		graph = new Graph(graphController);
+	}
+
+	@Test
+	public void testGraph() {
+		assertNotNull(new Graph(graphController));
+	}
+
+	@Test
+	public void testAddEdge() {
+		GraphEdge newEdge = new GraphEdge(graphController);
+		graph.addEdge(newEdge);
+		assertEquals(1, graph.getEdges().size());
+		assertTrue(graph.getEdges().contains(newEdge));
+	}
+
+	@Test
+	public void testAddNode() {
+		GraphNode newNode = new GraphNode(graphController);
+		graph.addNode(newNode);
+		assertEquals(1, graph.getNodes().size());
+		assertTrue(graph.getNodes().contains(newNode));
+		assertEquals(graph, newNode.getParent());
+	}
+
+	@Test
+	public void testAddSubgraph() {
+		Graph newGraph = new Graph(graphController);
+		graph.addSubgraph(newGraph);
+		assertEquals(1, graph.getSubgraphs().size());
+		assertTrue(graph.getSubgraphs().contains(newGraph));
+		assertEquals(graph, newGraph.getParent());
+	}
+
+	@Test
+	public void testGetAlignment() {
+		assertEquals(alignment, graph.getAlignment());
+	}
+
+	@Test
+	public void testGetEdges() {
+		assertNotNull(graph.getNodes());
+		assertEquals(0, graph.getNodes().size());
+	}
+
+	@Test
+	public void testGetNodes() {
+		assertNotNull(graph.getEdges());
+		assertEquals(0, graph.getEdges().size());
+	}
+
+	@Test
+	public void testGetSubgraphs() {
+		assertNotNull(graph.getSubgraphs());
+		assertEquals(0, graph.getSubgraphs().size());
+	}
+
+	@Test
+	public void testRemoveEdge() {
+		GraphEdge newEdge = new GraphEdge(graphController);
+		assertFalse(graph.removeEdge(newEdge));
+		graph.addEdge(newEdge);
+		assertTrue(graph.removeEdge(newEdge));
+		assertFalse(graph.getNodes().contains(newEdge));
+	}
+
+	@Test
+	public void testRemoveNode() {
+		GraphNode newNode = new GraphNode(graphController);
+		assertFalse(graph.removeNode(newNode));
+		graph.addNode(newNode);
+		assertTrue(graph.removeNode(newNode));
+		assertFalse(graph.getNodes().contains(newNode));
+	}
+
+	@Test
+	public void testRemoveSubgraph() {
+		Graph newGraph = new Graph(graphController);
+		assertFalse(graph.removeSubgraph(newGraph));
+		graph.addSubgraph(newGraph);
+		assertTrue(graph.removeSubgraph(newGraph));
+		assertFalse(graph.getSubgraphs().contains(newGraph));
+	}
+
+	@Test
+	public void testSetAlignment() {
+		graph.setAlignment(Alignment.VERTICAL);
+		assertEquals(Alignment.VERTICAL, graph.getAlignment());
+		graph.setAlignment(Alignment.HORIZONTAL);
+		assertEquals(Alignment.HORIZONTAL, graph.getAlignment());
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-model/src/test/resources/nested_iteration.xml
----------------------------------------------------------------------
diff --git a/taverna-graph-model/src/test/resources/nested_iteration.xml b/taverna-graph-model/src/test/resources/nested_iteration.xml
new file mode 100644
index 0000000..3675361
--- /dev/null
+++ b/taverna-graph-model/src/test/resources/nested_iteration.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<s:scufl xmlns:s="http://org.embl.ebi.escience/xscufl/0.1alpha" version="0.2" log="0">
+  <s:workflowdescription lsid="urn:lsid:net.sf.taverna:wfDefinition:c7016fc0-c2f4-4171-b6f1-430f408f4822" author="" title="nested_iteration" />
+  <s:processor name="constant" boring="true">
+    <s:stringconstant>constant</s:stringconstant>
+  </s:processor>
+  <s:processor name="generate_list">
+    <s:defaults>
+      <s:default name="prefix">prefix</s:default>
+    </s:defaults>
+    <s:beanshell>
+      <s:scriptvalue>list = new ArrayList();
+for (int i = 0; i &lt; 20; i++) {
+ list.add(prefix + i);
+}</s:scriptvalue>
+      <s:beanshellinputlist>
+        <s:beanshellinput s:syntactictype="'text/plain'">prefix</s:beanshellinput>
+      </s:beanshellinputlist>
+      <s:beanshelloutputlist>
+        <s:beanshelloutput s:syntactictype="l('text/plain')">list</s:beanshelloutput>
+      </s:beanshelloutputlist>
+      <s:dependencies s:classloader="iteration" />
+    </s:beanshell>
+  </s:processor>
+  <s:processor name="merge">
+    <s:workflow>
+      <s:scufl version="0.2" log="0">
+        <s:workflowdescription lsid="urn:lsid:net.sf.taverna:wfDefinition:3368fb8d-ecc7-4fcd-b511-6ace84b13c81" author="" title="Untitled workflow #24" />
+        <s:processor name="Nested_Workflow">
+          <s:workflow>
+            <s:scufl version="0.2" log="0">
+              <s:workflowdescription lsid="urn:lsid:net.sf.taverna:wfDefinition:75b99c76-7a76-4d3c-8d39-8c48df3355ad" author="" title="Untitled workflow #36" />
+              <s:processor name="concat">
+                <s:beanshell>
+                  <s:scriptvalue>Thread.sleep(200);
+out = in1 + in2;</s:scriptvalue>
+                  <s:beanshellinputlist>
+                    <s:beanshellinput s:syntactictype="'text/plain'">in1</s:beanshellinput>
+                    <s:beanshellinput s:syntactictype="'text/plain'">in2</s:beanshellinput>
+                  </s:beanshellinputlist>
+                  <s:beanshelloutputlist>
+                    <s:beanshelloutput s:syntactictype="'text/plain'">out</s:beanshelloutput>
+                  </s:beanshelloutputlist>
+                  <s:dependencies s:classloader="iteration" />
+                </s:beanshell>
+              </s:processor>
+              <s:link source="in1" sink="concat:in1" />
+              <s:link source="in2" sink="concat:in2" />
+              <s:link source="concat:out" sink="out" />
+              <s:source name="in1" />
+              <s:source name="in2" />
+              <s:sink name="out" />
+            </s:scufl>
+          </s:workflow>
+        </s:processor>
+        <s:link source="in1" sink="Nested_Workflow:in1" />
+        <s:link source="in2" sink="Nested_Workflow:in2" />
+        <s:link source="Nested_Workflow:out" sink="out" />
+        <s:source name="in1" />
+        <s:source name="in2" />
+        <s:sink name="out" />
+      </s:scufl>
+    </s:workflow>
+    <s:mergemode input="in2" mode="merge" />
+  </s:processor>
+  <s:link source="constant:value" sink="constant" />
+  <s:link source="constant:value" sink="merge:in1" />
+  <s:link source="generate_list:list" sink="list" />
+  <s:link source="generate_list:list" sink="merge:in2" />
+  <s:link source="generate_list:list" sink="merge:in2" />
+  <s:link source="merge:out" sink="concat" />
+  <s:source name="input" />
+  <s:sink name="concat">
+    <s:metadata>
+      <s:mimeTypes>
+        <s:mimeType>'text/plain'</s:mimeType>
+      </s:mimeTypes>
+    </s:metadata>
+  </s:sink>
+  <s:sink name="list">
+    <s:metadata>
+      <s:mimeTypes>
+        <s:mimeType>l('text/plain')</s:mimeType>
+      </s:mimeTypes>
+    </s:metadata>
+  </s:sink>
+  <s:sink name="constant">
+    <s:metadata>
+      <s:mimeTypes>
+        <s:mimeType>'text/plain'</s:mimeType>
+      </s:mimeTypes>
+    </s:metadata>
+  </s:sink>
+  <s:coordination name="constant_BLOCKON_generate_list">
+    <s:condition>
+      <s:state>Completed</s:state>
+      <s:target>generate_list</s:target>
+    </s:condition>
+    <s:action>
+      <s:target>constant</s:target>
+      <s:statechange>
+        <s:from>Scheduled</s:from>
+        <s:to>Running</s:to>
+      </s:statechange>
+    </s:action>
+  </s:coordination>
+  <s:coordination name="merge_BLOCKON_generate_list">
+    <s:condition>
+      <s:state>Completed</s:state>
+      <s:target>generate_list</s:target>
+    </s:condition>
+    <s:action>
+      <s:target>merge</s:target>
+      <s:statechange>
+        <s:from>Scheduled</s:from>
+        <s:to>Running</s:to>
+      </s:statechange>
+    </s:action>
+  </s:coordination>
+</s:scufl>
+

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-view/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-graph-view/pom.xml b/taverna-graph-view/pom.xml
new file mode 100644
index 0000000..56e0587
--- /dev/null
+++ b/taverna-graph-view/pom.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.apache.taverna.workbench</groupId>
+		<artifactId>taverna-workbench</artifactId>
+		<version>3.1.0-incubating-SNAPSHOT</version>
+	</parent>
+	<artifactId>graph-view</artifactId>
+	<packaging>taverna-bundle</packaging>
+	<name>Apache Taverna Graph View</name>
+	<dependencies>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-workbench-api</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-configuration-api</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-file-api</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-menu-api</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-design-ui</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-workflow-view</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-graph-model</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.engine</groupId>
+			<artifactId>taverna-observer</artifactId>
+			<version>${taverna.engine.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-ui</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-io</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.osgi</groupId>
+			<artifactId>taverna-services-api</artifactId>
+			<version>${taverna.osgi.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.language</groupId>
+			<artifactId>taverna-scufl2-api</artifactId>
+			<version>${taverna.language.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.batik</groupId>
+			<artifactId>batik-osgi</artifactId>
+			<version>${batik.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>log4j</groupId>
+			<artifactId>log4j</artifactId>
+			<version>${log4j.version}</version>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/AutoScrollInteractor.java
----------------------------------------------------------------------
diff --git a/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/AutoScrollInteractor.java b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/AutoScrollInteractor.java
new file mode 100644
index 0000000..65a4aa5
--- /dev/null
+++ b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/AutoScrollInteractor.java
@@ -0,0 +1,181 @@
+package net.sf.taverna.t2.workbench.views.graph;
+
+import static java.awt.event.InputEvent.BUTTON1_DOWN_MASK;
+import static java.awt.event.InputEvent.BUTTON1_MASK;
+import static java.awt.event.MouseEvent.BUTTON1;
+import static java.awt.event.MouseEvent.MOUSE_DRAGGED;
+import static java.awt.event.MouseEvent.MOUSE_PRESSED;
+import static java.lang.System.currentTimeMillis;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.awt.geom.AffineTransform;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.apache.batik.swing.JSVGCanvas;
+import org.apache.batik.swing.gvt.InteractorAdapter;
+import org.apache.batik.swing.gvt.JGVTComponent;
+
+/**
+ * An interactor that scrolls the canvas view if the mouse is dragged to the
+ * edge of the canvas.
+ * 
+ * @author David Withers
+ */
+public class AutoScrollInteractor extends InteractorAdapter {
+	/**
+	 * Defines the border around the canvas in which the auto scroll will become
+	 * active.
+	 */
+	private static final int BORDER = 25;
+	/**
+	 * The interval, in milliseconds, between scroll events.
+	 */
+	private static final long SCROLL_INTERVAL = 100;
+
+	private JSVGCanvas svgCanvas;
+	private Dimension canvasSize;
+	private int scrollX;
+	private int scrollY;
+	private int mouseX;
+	private int mouseY;
+
+	/**
+	 * Component used to identify mouse events generated by this class
+	 */
+	private Component eventIdentifier = new Component() {
+		private static final long serialVersionUID = -295542754718804222L;
+	};
+
+	private static Timer timer = new Timer("GraphAutoScrollTimer", true);
+
+	private TimerTask task;
+
+	/**
+	 * Whether the interactor has finished.
+	 */
+	protected boolean finished = true;
+
+	public AutoScrollInteractor(JSVGCanvas svgCanvas) {
+		this.svgCanvas = svgCanvas;
+	}
+
+	@Override
+	public boolean startInteraction(InputEvent ie) {
+		int mods = ie.getModifiers();
+		if (ie.getID() == MOUSE_PRESSED && (mods & BUTTON1_MASK) != 0) {
+			AffineTransform transform = svgCanvas.getRenderingTransform();
+			// check if we're zoomed in
+			if (transform.getScaleX() > 1d || transform.getScaleY() > 1d) {
+				canvasSize = svgCanvas.getSize();
+				return true;
+			}
+		}
+		return false;
+	}
+
+	@Override
+	public boolean endInteraction() {
+		return finished;
+	}
+
+	@Override
+	public void mousePressed(final MouseEvent e) {
+		if (startInteraction(e)) {
+			finished = false;
+			task = new TimerTask() {
+				@Override
+				public void run() {
+					scrollTimerCallback(e);
+				}
+			};
+			timer.schedule(task, 0, SCROLL_INTERVAL);
+		}
+	}
+
+	/**
+	 * Dispatches a mouse drag event that updates the mouse location by the
+	 * amount that the canvas has been scrolled.
+	 * 
+	 * @param dragX
+	 * @param dragY
+	 */
+	private void dispatchDragEvent(double dragX, double dragY) {
+		int x = (int) (mouseX + dragX);
+		int y = (int) (mouseY + dragY);
+		MouseEvent mouseDragEvent = new MouseEvent(eventIdentifier,
+				MOUSE_DRAGGED, currentTimeMillis(), BUTTON1_DOWN_MASK, x, y, 1,
+				false, BUTTON1);
+		svgCanvas.dispatchEvent(mouseDragEvent);
+	}
+
+	@Override
+	public void mouseReleased(MouseEvent e) {
+		if (!finished) {
+			finished = true;
+			scrollX = 0;
+			scrollY = 0;
+			if (task != null)
+				task.cancel();
+		}
+	}
+
+	@Override
+	public void mouseDragged(MouseEvent e) {
+		// ignore events generated by this class
+		if (!finished && e.getSource() != eventIdentifier) {
+			mouseX = e.getX();
+			mouseY = e.getY();
+			int minX = BORDER;
+			int maxX = canvasSize.width - BORDER;
+			int minY = BORDER;
+			int maxY = canvasSize.height - BORDER;
+
+			scrollX = (mouseX < minX) ? (minX - mouseX)
+					: (mouseX > maxX) ? (maxX - mouseX) : 0;
+			scrollY = (mouseY < minY) ? (minY - mouseY)
+					: (mouseY > maxY) ? (maxY - mouseY) : 0;
+		}
+	}
+
+	private void scrollTimerCallback(MouseEvent e) {
+		double x = scrollX;
+		double y = scrollY;
+		if (x == 0 && y == 0)
+			return;
+
+		JGVTComponent c = (JGVTComponent) e.getSource();
+		AffineTransform rt = (AffineTransform) c.getRenderingTransform()
+				.clone();
+		double currentTranslateX = rt.getTranslateX();
+		double currentTranslateY = rt.getTranslateY();
+		// the tranlation that will show the east edge
+		double maxTranslateX = -((canvasSize.width * rt.getScaleX()) - canvasSize.width);
+		// the translation that will show the south
+		double maxTranslateY = -((canvasSize.height * rt.getScaleY()) - canvasSize.height);
+
+		if (x > 0 && currentTranslateX + x > 0)
+			// scroll left && not at west edge
+			x = -currentTranslateX;
+		else if (x < 0 && currentTranslateX + x < maxTranslateX)
+			// scroll right && not at east edge
+			x = maxTranslateX - currentTranslateX;
+
+		if (y > 0 && currentTranslateY + y > 0)
+			// scroll up && not at north edge
+			y = -currentTranslateY;
+		else if (y < 0 && currentTranslateY + y < maxTranslateY)
+			// scroll down && not at south edge
+			y = maxTranslateY - currentTranslateY;
+
+		if (x != 0d || y != 0d) {
+			AffineTransform at = AffineTransform.getTranslateInstance(x, y);
+			rt.preConcatenate(at);
+			c.setRenderingTransform(rt);
+			dispatchDragEvent(x, y);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/GraphViewComponent.java
----------------------------------------------------------------------
diff --git a/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/GraphViewComponent.java b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/GraphViewComponent.java
new file mode 100644
index 0000000..55bcf3f
--- /dev/null
+++ b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/GraphViewComponent.java
@@ -0,0 +1,548 @@
+/*******************************************************************************
+ * 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.views.graph;
+
+import static java.awt.BorderLayout.CENTER;
+import static java.awt.BorderLayout.NORTH;
+import static javax.swing.Action.SHORT_DESCRIPTION;
+import static javax.swing.Action.SMALL_ICON;
+import static javax.swing.BoxLayout.PAGE_AXIS;
+import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.allportIcon;
+import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.blobIcon;
+import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.expandNestedIcon;
+import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.horizontalIcon;
+import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.noportIcon;
+import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.refreshIcon;
+import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.verticalIcon;
+import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.zoomInIcon;
+import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.zoomOutIcon;
+import static net.sf.taverna.t2.workbench.views.graph.config.GraphViewConfiguration.ALIGNMENT;
+import static net.sf.taverna.t2.workbench.views.graph.config.GraphViewConfiguration.ANIMATION_ENABLED;
+import static net.sf.taverna.t2.workbench.views.graph.config.GraphViewConfiguration.ANIMATION_SPEED;
+import static net.sf.taverna.t2.workbench.views.graph.config.GraphViewConfiguration.PORT_STYLE;
+import static org.apache.batik.swing.svg.AbstractJSVGComponent.ALWAYS_DYNAMIC;
+
+import java.awt.BorderLayout;
+import java.awt.CardLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.BoxLayout;
+import javax.swing.ButtonGroup;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
+import javax.swing.Timer;
+import javax.swing.border.EmptyBorder;
+
+import net.sf.taverna.t2.lang.observer.Observable;
+import net.sf.taverna.t2.lang.observer.SwingAwareObserver;
+import net.sf.taverna.t2.ui.menu.MenuManager;
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+import net.sf.taverna.t2.workbench.configuration.workbench.WorkbenchConfiguration;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.edits.EditManager.AbstractDataflowEditEvent;
+import net.sf.taverna.t2.workbench.edits.EditManager.EditManagerEvent;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.file.events.ClosedDataflowEvent;
+import net.sf.taverna.t2.workbench.file.events.FileManagerEvent;
+import net.sf.taverna.t2.workbench.models.graph.Graph.Alignment;
+import net.sf.taverna.t2.workbench.models.graph.GraphController;
+import net.sf.taverna.t2.workbench.models.graph.GraphController.PortStyle;
+import net.sf.taverna.t2.workbench.models.graph.svg.SVGGraphController;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import net.sf.taverna.t2.workbench.selection.events.SelectionManagerEvent;
+import net.sf.taverna.t2.workbench.selection.events.WorkflowBundleSelectionEvent;
+import net.sf.taverna.t2.workbench.selection.events.WorkflowSelectionEvent;
+import net.sf.taverna.t2.workbench.ui.dndhandler.ServiceTransferHandler;
+import net.sf.taverna.t2.workbench.ui.zaria.UIComponentSPI;
+import net.sf.taverna.t2.workbench.views.graph.config.GraphViewConfiguration;
+import net.sf.taverna.t2.workbench.views.graph.menu.ResetDiagramAction;
+import net.sf.taverna.t2.workbench.views.graph.menu.ZoomInAction;
+import net.sf.taverna.t2.workbench.views.graph.menu.ZoomOutAction;
+
+import org.apache.batik.swing.JSVGCanvas;
+import org.apache.batik.swing.JSVGScrollPane;
+import org.apache.batik.swing.gvt.GVTTreeRendererAdapter;
+import org.apache.batik.swing.gvt.GVTTreeRendererEvent;
+import org.apache.log4j.Logger;
+
+import uk.org.taverna.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.core.Workflow;
+
+/**
+ * @author David Withers
+ * @author Alex Nenadic
+ * @author Tom Oinn
+ */
+public class GraphViewComponent extends JPanel implements UIComponentSPI {
+	private static final long serialVersionUID = 7404937056378331528L;
+	private static final Logger logger = Logger.getLogger(GraphViewComponent.class);
+
+	private Workflow workflow;
+	private SVGGraphController graphController;
+	private JPanel diagramPanel;
+
+	private Map<WorkflowBundle, Set<Workflow>> workflowsMap = new IdentityHashMap<>();
+
+	private Map<Workflow, SVGGraphController> graphControllerMap = new IdentityHashMap<>();
+	private Map<Workflow, JPanel> diagramPanelMap = new IdentityHashMap<>();
+	private Map<Workflow, Action[]> diagramActionsMap = new IdentityHashMap<>();
+
+	private Timer timer;
+
+	private CardLayout cardLayout;
+
+	private final ColourManager colourManager;
+	private final EditManager editManager;
+	private final MenuManager menuManager;
+	private final GraphViewConfiguration graphViewConfiguration;
+	private final WorkbenchConfiguration workbenchConfiguration;
+	private final SelectionManager selectionManager;
+	private final ServiceRegistry serviceRegistry;
+
+	public GraphViewComponent(ColourManager colourManager,
+			EditManager editManager, FileManager fileManager,
+			MenuManager menuManager,
+			GraphViewConfiguration graphViewConfiguration,
+			WorkbenchConfiguration workbenchConfiguration,
+			SelectionManager selectionManager, ServiceRegistry serviceRegistry) {
+		this.colourManager = colourManager;
+		this.editManager = editManager;
+		this.menuManager = menuManager;
+		this.graphViewConfiguration = graphViewConfiguration;
+		this.workbenchConfiguration = workbenchConfiguration;
+		this.selectionManager = selectionManager;
+		this.serviceRegistry = serviceRegistry;
+
+		cardLayout = new CardLayout();
+		setLayout(cardLayout);
+
+		ActionListener taskPerformer = new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent evt) {
+				if (graphController != null)
+					graphController.redraw();
+				timer.stop();
+			}
+		};
+		timer = new Timer(100, taskPerformer);
+
+		addComponentListener(new ComponentAdapter() {
+			@Override
+			public void componentResized(ComponentEvent e) {
+				if (timer.isRunning())
+					timer.restart();
+				else
+					timer.start();
+			}
+		});
+
+		editManager.addObserver(new EditManagerObserver());
+		selectionManager.addObserver(new SelectionManagerObserver());
+		fileManager.addObserver(new FileManagerObserver());
+	}
+
+	@Override
+	protected void finalize() throws Throwable {
+		if (timer != null)
+			timer.stop();
+	}
+
+	@Override
+	public String getName() {
+		return "Graph View Component";
+	}
+
+	@Override
+	public ImageIcon getIcon() {
+		return null;
+	}
+
+	@Override
+	public void onDisplay() {
+	}
+
+	@Override
+	public void onDispose() {
+		if (timer != null)
+			timer.stop();
+	}
+
+	private JPanel createDiagramPanel(Workflow workflow) {
+		final JPanel diagramPanel = new JPanel(new BorderLayout());
+
+		// get the default diagram settings
+		Alignment alignment = Alignment.valueOf(graphViewConfiguration
+				.getProperty(ALIGNMENT));
+		PortStyle portStyle = PortStyle.valueOf(graphViewConfiguration
+				.getProperty(PORT_STYLE));
+		boolean animationEnabled = Boolean.parseBoolean(graphViewConfiguration
+				.getProperty(ANIMATION_ENABLED));
+		int animationSpeed = Integer.parseInt(graphViewConfiguration
+				.getProperty(ANIMATION_SPEED));
+
+		// create an SVG canvas
+		final JSVGCanvas svgCanvas = new JSVGCanvas(null, true, false);
+		svgCanvas.setEnableZoomInteractor(false);
+		svgCanvas.setEnableRotateInteractor(false);
+		svgCanvas.setDocumentState(ALWAYS_DYNAMIC);
+		svgCanvas.setTransferHandler(new ServiceTransferHandler(editManager,
+				menuManager, selectionManager, serviceRegistry));
+
+		AutoScrollInteractor asi = new AutoScrollInteractor(svgCanvas);
+		svgCanvas.addMouseListener(asi);
+		svgCanvas.addMouseMotionListener(asi);
+
+		final JSVGScrollPane svgScrollPane = new MySvgScrollPane(svgCanvas);
+
+		GVTTreeRendererAdapter gvtTreeRendererAdapter = new GVTTreeRendererAdapter() {
+			@Override
+			public void gvtRenderingCompleted(GVTTreeRendererEvent e) {
+				logger.info("Rendered svg");
+				svgScrollPane.reset();
+				diagramPanel.revalidate();
+			}
+		};
+		svgCanvas.addGVTTreeRendererListener(gvtTreeRendererAdapter);
+
+		// create a graph controller
+		SVGGraphController svgGraphController = new SVGGraphController(
+				workflow, selectionManager.getSelectedProfile(), false,
+				svgCanvas, alignment, portStyle, editManager, menuManager,
+				colourManager, workbenchConfiguration);
+		svgGraphController.setDataflowSelectionModel(selectionManager
+				.getDataflowSelectionModel(workflow.getParent()));
+		svgGraphController.setAnimationSpeed(animationEnabled ? animationSpeed
+				: 0);
+
+		graphControllerMap.put(workflow, svgGraphController);
+
+		// Toolbar with actions related to graph
+		JToolBar graphActionsToolbar = graphActionsToolbar(workflow,
+				svgGraphController, svgCanvas, alignment, portStyle);
+		graphActionsToolbar.setAlignmentX(LEFT_ALIGNMENT);
+		graphActionsToolbar.setFloatable(false);
+
+		// Panel to hold the toolbars
+		JPanel toolbarPanel = new JPanel();
+		toolbarPanel.setLayout(new BoxLayout(toolbarPanel, PAGE_AXIS));
+		toolbarPanel.add(graphActionsToolbar);
+
+		diagramPanel.add(toolbarPanel, NORTH);
+		diagramPanel.add(svgScrollPane, CENTER);
+
+		// JTextField workflowHierarchy = new JTextField(workflow.getName());
+		// diagramPanel.add(workflowHierarchy, BorderLayout.SOUTH);
+
+		return diagramPanel;
+	}
+
+	@SuppressWarnings("serial")
+	private JToolBar graphActionsToolbar(Workflow workflow,
+			final SVGGraphController graphController, JSVGCanvas svgCanvas,
+			Alignment alignment, PortStyle portStyle) {
+		JToolBar toolBar = new JToolBar();
+
+		JButton resetDiagramButton = new JButton();
+		resetDiagramButton.setBorder(new EmptyBorder(0, 2, 0, 2));
+		JButton zoomInButton = new JButton();
+		zoomInButton.setBorder(new EmptyBorder(0, 2, 0, 2));
+		JButton zoomOutButton = new JButton();
+		zoomOutButton.setBorder(new EmptyBorder(0, 2, 0, 2));
+
+		Action resetDiagramAction = svgCanvas.new ResetTransformAction();
+		ResetDiagramAction.setDesignAction(resetDiagramAction);
+		resetDiagramAction.putValue(SHORT_DESCRIPTION, "Reset Diagram");
+		resetDiagramAction.putValue(SMALL_ICON, refreshIcon);
+		resetDiagramButton.setAction(resetDiagramAction);
+
+		Action zoomInAction = svgCanvas.new ZoomAction(1.2);
+		ZoomInAction.setDesignAction(zoomInAction);
+		zoomInAction.putValue(SHORT_DESCRIPTION, "Zoom In");
+		zoomInAction.putValue(SMALL_ICON, zoomInIcon);
+		zoomInButton.setAction(zoomInAction);
+
+		Action zoomOutAction = svgCanvas.new ZoomAction(1 / 1.2);
+		ZoomOutAction.setDesignAction(zoomOutAction);
+		zoomOutAction.putValue(SHORT_DESCRIPTION, "Zoom Out");
+		zoomOutAction.putValue(SMALL_ICON, zoomOutIcon);
+		zoomOutButton.setAction(zoomOutAction);
+
+		diagramActionsMap.put(workflow, new Action[] { resetDiagramAction,
+				zoomInAction, zoomOutAction });
+
+		toolBar.add(resetDiagramButton);
+		toolBar.add(zoomInButton);
+		toolBar.add(zoomOutButton);
+
+		toolBar.addSeparator();
+
+		ButtonGroup nodeTypeGroup = new ButtonGroup();
+
+		JToggleButton noPorts = new JToggleButton();
+		JToggleButton allPorts = new JToggleButton();
+		JToggleButton blobs = new JToggleButton();
+		nodeTypeGroup.add(noPorts);
+		nodeTypeGroup.add(allPorts);
+		nodeTypeGroup.add(blobs);
+
+		if (portStyle.equals(PortStyle.NONE))
+			noPorts.setSelected(true);
+		else if (portStyle.equals(PortStyle.ALL))
+			allPorts.setSelected(true);
+		else
+			blobs.setSelected(true);
+
+		noPorts.setAction(new AbstractAction() {
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				graphController.setPortStyle(PortStyle.NONE);
+				graphController.redraw();
+			}
+		});
+		noPorts.getAction().putValue(SHORT_DESCRIPTION,
+				"Display no service ports");
+		noPorts.getAction().putValue(SMALL_ICON, noportIcon);
+		noPorts.setFocusPainted(false);
+
+		allPorts.setAction(new AbstractAction() {
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				graphController.setPortStyle(PortStyle.ALL);
+				graphController.redraw();
+			}
+		});
+		allPorts.getAction().putValue(SHORT_DESCRIPTION,
+				"Display all service ports");
+		allPorts.getAction().putValue(SMALL_ICON, allportIcon);
+		allPorts.setFocusPainted(false);
+
+		blobs.setAction(new AbstractAction() {
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				graphController.setPortStyle(PortStyle.BLOB);
+				graphController.redraw();
+			}
+		});
+		blobs.getAction().putValue(SHORT_DESCRIPTION,
+				"Display services as circles");
+		blobs.getAction().putValue(SMALL_ICON, blobIcon);
+		blobs.setFocusPainted(false);
+
+		toolBar.add(noPorts);
+		toolBar.add(allPorts);
+		toolBar.add(blobs);
+
+		toolBar.addSeparator();
+
+		ButtonGroup alignmentGroup = new ButtonGroup();
+
+		JToggleButton vertical = new JToggleButton();
+		JToggleButton horizontal = new JToggleButton();
+		alignmentGroup.add(vertical);
+		alignmentGroup.add(horizontal);
+
+		if (alignment.equals(Alignment.VERTICAL)) {
+			vertical.setSelected(true);
+		} else {
+			horizontal.setSelected(true);
+		}
+
+		vertical.setAction(new AbstractAction() {
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				graphController.setAlignment(Alignment.VERTICAL);
+				graphController.redraw();
+			}
+		});
+		vertical.getAction().putValue(SHORT_DESCRIPTION,
+				"Align services vertically");
+		vertical.getAction().putValue(SMALL_ICON, verticalIcon);
+		vertical.setFocusPainted(false);
+
+		horizontal.setAction(new AbstractAction() {
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				graphController.setAlignment(Alignment.HORIZONTAL);
+				graphController.redraw();
+			}
+
+		});
+		horizontal.getAction().putValue(SHORT_DESCRIPTION,
+				"Align services horizontally");
+		horizontal.getAction().putValue(SMALL_ICON, horizontalIcon);
+		horizontal.setFocusPainted(false);
+
+		toolBar.add(vertical);
+		toolBar.add(horizontal);
+
+		toolBar.addSeparator();
+
+		JToggleButton expandNested = new JToggleButton();
+		expandNested.setSelected(true);
+
+		expandNested.setAction(new AbstractAction() {
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				graphController.setExpandNestedDataflows(!graphController
+						.expandNestedDataflows());
+				graphController.redraw();
+			}
+		});
+		expandNested.getAction().putValue(SHORT_DESCRIPTION,
+				"Expand Nested Workflows");
+		expandNested.getAction().putValue(SMALL_ICON, expandNestedIcon);
+		expandNested.setFocusPainted(false);
+		toolBar.add(expandNested);
+
+		return toolBar;
+	}
+
+	/**
+	 * Sets the Workflow to display in the graph view.
+	 *
+	 * @param workflow
+	 */
+	private void setWorkflow(Workflow workflow) {
+		this.workflow = workflow;
+		if (!diagramPanelMap.containsKey(workflow))
+			addWorkflow(workflow);
+		graphController = graphControllerMap.get(workflow);
+		diagramPanel = diagramPanelMap.get(workflow);
+		Action[] actions = diagramActionsMap.get(workflow);
+		if (actions != null && actions.length == 3) {
+			ResetDiagramAction.setDesignAction(actions[0]);
+			ZoomInAction.setDesignAction(actions[1]);
+			ZoomOutAction.setDesignAction(actions[2]);
+		}
+		cardLayout.show(this, String.valueOf(diagramPanel.hashCode()));
+		graphController.redraw();
+	}
+
+	private void addWorkflow(Workflow workflow) {
+		JPanel newDiagramPanel = createDiagramPanel(workflow);
+		add(newDiagramPanel, String.valueOf(newDiagramPanel.hashCode()));
+		diagramPanelMap.put(workflow, newDiagramPanel);
+		if (!workflowsMap.containsKey(workflow.getParent()))
+			workflowsMap.put(workflow.getParent(), new HashSet<Workflow>());
+		workflowsMap.get(workflow.getParent()).add(workflow);
+	}
+
+	private void removeWorkflow(Workflow workflow) {
+		JPanel panel = diagramPanelMap.remove(workflow);
+		if (panel != null)
+			remove(panel);
+		SVGGraphController removedController = graphControllerMap.remove(workflow);
+		if (removedController != null)
+			removedController.shutdown();
+		diagramActionsMap.remove(workflow);
+		Set<Workflow> workflows = workflowsMap.get(workflow.getParent());
+		if (workflows != null)
+			workflows.remove(workflow);
+	}
+
+	public GraphController getGraphController(Workflow workflow) {
+		return graphControllerMap.get(workflow);
+	}
+
+	private class EditManagerObserver extends
+			SwingAwareObserver<EditManagerEvent> {
+		@Override
+		public void notifySwing(Observable<EditManagerEvent> sender,
+				EditManagerEvent message) {
+			if (!(message instanceof AbstractDataflowEditEvent))
+				return;
+			AbstractDataflowEditEvent dataflowEditEvent = (AbstractDataflowEditEvent) message;
+			if (dataflowEditEvent.getDataFlow() != workflow.getParent())
+				return;
+			
+			boolean animationEnabled = Boolean
+					.parseBoolean(graphViewConfiguration
+							.getProperty(ANIMATION_ENABLED));
+			int animationSpeed = (animationEnabled ? Integer
+					.parseInt(graphViewConfiguration
+							.getProperty(ANIMATION_SPEED)) : 0);
+			boolean animationSettingChanged = (animationEnabled != (graphController
+					.getAnimationSpeed() != 0));
+
+			if (graphController.isDotMissing() || animationSettingChanged) {
+				removeWorkflow(workflow);
+				setWorkflow(workflow);
+			} else {
+				if (animationSpeed != graphController.getAnimationSpeed())
+					graphController.setAnimationSpeed(animationSpeed);
+				graphController.redraw();
+			}
+		}
+	}
+
+	private class FileManagerObserver extends SwingAwareObserver<FileManagerEvent> {
+		@Override
+		public void notifySwing(Observable<FileManagerEvent> sender, final FileManagerEvent message) {
+			if (!(message instanceof ClosedDataflowEvent))
+				return;
+			ClosedDataflowEvent closedDataflowEvent = (ClosedDataflowEvent) message;
+
+			WorkflowBundle workflowBundle = closedDataflowEvent.getDataflow();
+			if (workflowsMap.containsKey(workflowBundle))
+				for (Workflow workflow : workflowsMap.remove(workflowBundle))
+					removeWorkflow(workflow);
+		}
+	}
+
+	private class SelectionManagerObserver extends
+			SwingAwareObserver<SelectionManagerEvent> {
+		@Override
+		public void notifySwing(Observable<SelectionManagerEvent> sender,
+				SelectionManagerEvent message) {
+			if (message instanceof WorkflowSelectionEvent)
+				setWorkflow(selectionManager.getSelectedWorkflow());
+			else if (message instanceof WorkflowBundleSelectionEvent)
+				setWorkflow(selectionManager.getSelectedWorkflow());
+		}
+	}
+
+	private class MySvgScrollPane extends JSVGScrollPane {
+		private static final long serialVersionUID = -1539947450704269879L;
+
+		public MySvgScrollPane(JSVGCanvas canvas) {
+			super(canvas);
+		}
+
+		@Override
+		public void reset() {
+			super.resizeScrollBars();
+			super.reset();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/GraphViewComponentFactory.java
----------------------------------------------------------------------
diff --git a/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/GraphViewComponentFactory.java b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/GraphViewComponentFactory.java
new file mode 100644
index 0000000..85f2929
--- /dev/null
+++ b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/GraphViewComponentFactory.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * 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.views.graph;
+
+import javax.swing.ImageIcon;
+
+import uk.org.taverna.commons.services.ServiceRegistry;
+
+import net.sf.taverna.t2.ui.menu.MenuManager;
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+import net.sf.taverna.t2.workbench.configuration.workbench.WorkbenchConfiguration;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import net.sf.taverna.t2.workbench.ui.zaria.UIComponentFactorySPI;
+import net.sf.taverna.t2.workbench.ui.zaria.UIComponentSPI;
+import net.sf.taverna.t2.workbench.views.graph.config.GraphViewConfiguration;
+
+/**
+ * @author David Withers
+ */
+public class GraphViewComponentFactory implements UIComponentFactorySPI {
+	private EditManager editManager;
+	private FileManager fileManager;
+	private MenuManager menuManager;
+	private SelectionManager selectionManager;
+	private ColourManager colourManager;
+	private WorkbenchConfiguration workbenchConfiguration;
+	private GraphViewConfiguration graphViewConfiguration;
+	private ServiceRegistry serviceRegistry;
+
+	@Override
+	public UIComponentSPI getComponent() {
+		return new GraphViewComponent(colourManager, editManager, fileManager,
+				menuManager, graphViewConfiguration, workbenchConfiguration,
+				selectionManager, serviceRegistry);
+	}
+
+	@Override
+	public ImageIcon getIcon() {
+		return null;
+	}
+
+	@Override
+	public String getName() {
+		return "Graph View";
+	}
+
+	public void setEditManager(EditManager editManager) {
+		this.editManager = editManager;
+	}
+
+	public void setFileManager(FileManager fileManager) {
+		this.fileManager = fileManager;
+	}
+
+	public void setMenuManager(MenuManager menuManager) {
+		this.menuManager = menuManager;
+	}
+
+	public void setSelectionManager(SelectionManager selectionManager) {
+		this.selectionManager = selectionManager;
+	}
+
+	public void setColourManager(ColourManager colourManager) {
+		this.colourManager = colourManager;
+	}
+
+	public void setWorkbenchConfiguration(
+			WorkbenchConfiguration workbenchConfiguration) {
+		this.workbenchConfiguration = workbenchConfiguration;
+	}
+
+	public void setGraphViewConfiguration(
+			GraphViewConfiguration graphViewConfiguration) {
+		this.graphViewConfiguration = graphViewConfiguration;
+	}
+
+	public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+		this.serviceRegistry = serviceRegistry;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/AddWFInputAction.java
----------------------------------------------------------------------
diff --git a/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/AddWFInputAction.java b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/AddWFInputAction.java
new file mode 100644
index 0000000..8c16e4a
--- /dev/null
+++ b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/AddWFInputAction.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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.views.graph.actions;
+
+import static java.awt.event.InputEvent.ALT_DOWN_MASK;
+import static java.awt.event.InputEvent.SHIFT_DOWN_MASK;
+import static java.awt.event.KeyEvent.VK_I;
+import static javax.swing.KeyStroke.getKeyStroke;
+import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.inputIcon;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+
+import net.sf.taverna.t2.ui.menu.DesignOnlyAction;
+import net.sf.taverna.t2.workbench.design.actions.AddDataflowInputAction;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import uk.org.taverna.scufl2.api.core.Workflow;
+
+/**
+ * An action that adds a workflow input.
+ * 
+ * @author Alex Nenadic
+ * @author Alan R Williams
+ */
+@SuppressWarnings("serial")
+public class AddWFInputAction extends AbstractAction implements
+		DesignOnlyAction {
+	private final EditManager editManager;
+	private final SelectionManager selectionManager;
+
+	public AddWFInputAction(EditManager editManager,
+			SelectionManager selectionManager) {
+		super();
+		this.editManager = editManager;
+		this.selectionManager = selectionManager;
+		putValue(SMALL_ICON, inputIcon);
+		putValue(NAME, "Workflow input port");
+		putValue(SHORT_DESCRIPTION, "Workflow input port");
+		putValue(ACCELERATOR_KEY,
+				getKeyStroke(VK_I, SHIFT_DOWN_MASK | ALT_DOWN_MASK));
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		Workflow workflow = selectionManager.getSelectedWorkflow();
+		new AddDataflowInputAction(workflow, null, editManager,
+				selectionManager).actionPerformed(e);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/AddWFOutputAction.java
----------------------------------------------------------------------
diff --git a/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/AddWFOutputAction.java b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/AddWFOutputAction.java
new file mode 100644
index 0000000..4027773
--- /dev/null
+++ b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/AddWFOutputAction.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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.views.graph.actions;
+
+import static java.awt.event.InputEvent.ALT_DOWN_MASK;
+import static java.awt.event.InputEvent.SHIFT_DOWN_MASK;
+import static java.awt.event.KeyEvent.VK_O;
+import static javax.swing.KeyStroke.getKeyStroke;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+
+import net.sf.taverna.t2.ui.menu.DesignOnlyAction;
+import net.sf.taverna.t2.workbench.design.actions.AddDataflowOutputAction;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.icons.WorkbenchIcons;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import uk.org.taverna.scufl2.api.core.Workflow;
+
+/**
+ * An action that adds a workflow output.
+ * 
+ * @author Alex Nenadic
+ * @author Alan R Williams
+ */
+@SuppressWarnings("serial")
+public class AddWFOutputAction extends AbstractAction implements
+		DesignOnlyAction {
+	private final EditManager editManager;
+	private final SelectionManager selectionManager;
+
+	public AddWFOutputAction(EditManager editManager,
+			SelectionManager selectionManager) {
+		super();
+		this.editManager = editManager;
+		this.selectionManager = selectionManager;
+		putValue(SMALL_ICON, WorkbenchIcons.outputIcon);
+		putValue(NAME, "Workflow output port");
+		putValue(SHORT_DESCRIPTION, "Workflow output port");
+		putValue(ACCELERATOR_KEY,
+				getKeyStroke(VK_O, SHIFT_DOWN_MASK | ALT_DOWN_MASK));
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		Workflow workflow = selectionManager.getSelectedWorkflow();
+		new AddDataflowOutputAction(workflow, null, editManager,
+				selectionManager).actionPerformed(e);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/DeleteGraphComponentAction.java
----------------------------------------------------------------------
diff --git a/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/DeleteGraphComponentAction.java b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/DeleteGraphComponentAction.java
new file mode 100644
index 0000000..86849b6
--- /dev/null
+++ b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/DeleteGraphComponentAction.java
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * 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.views.graph.actions;
+
+import static java.awt.event.KeyEvent.VK_DELETE;
+import static javax.swing.KeyStroke.getKeyStroke;
+import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.deleteIcon;
+
+import java.awt.event.ActionEvent;
+import java.util.Set;
+
+import javax.swing.AbstractAction;
+
+import net.sf.taverna.t2.lang.observer.Observable;
+import net.sf.taverna.t2.lang.observer.Observer;
+import net.sf.taverna.t2.lang.observer.SwingAwareObserver;
+import net.sf.taverna.t2.ui.menu.DesignOnlyAction;
+import net.sf.taverna.t2.workbench.design.actions.RemoveConditionAction;
+import net.sf.taverna.t2.workbench.design.actions.RemoveDataflowInputPortAction;
+import net.sf.taverna.t2.workbench.design.actions.RemoveDataflowOutputPortAction;
+import net.sf.taverna.t2.workbench.design.actions.RemoveDatalinkAction;
+import net.sf.taverna.t2.workbench.design.actions.RemoveProcessorAction;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.selection.DataflowSelectionModel;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import net.sf.taverna.t2.workbench.selection.events.DataflowSelectionMessage;
+import net.sf.taverna.t2.workbench.selection.events.SelectionManagerEvent;
+import net.sf.taverna.t2.workbench.selection.events.WorkflowBundleSelectionEvent;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.core.ControlLink;
+import uk.org.taverna.scufl2.api.core.DataLink;
+import uk.org.taverna.scufl2.api.core.Processor;
+import uk.org.taverna.scufl2.api.port.InputWorkflowPort;
+import uk.org.taverna.scufl2.api.port.OutputWorkflowPort;
+
+/**
+ * An action that deletes the selected graph component.
+ *
+ * @author Alex Nenadic
+ */
+@SuppressWarnings("serial")
+public class DeleteGraphComponentAction extends AbstractAction implements DesignOnlyAction {
+	/** Current workflow's selection model event observer.*/
+	private Observer<DataflowSelectionMessage> workflowSelectionObserver = new DataflowSelectionObserver();
+
+	private final EditManager editManager;
+	private final SelectionManager selectionManager;
+
+	public DeleteGraphComponentAction(EditManager editManager, final SelectionManager selectionManager) {
+		super();
+		this.editManager = editManager;
+		this.selectionManager = selectionManager;
+		putValue(SMALL_ICON, deleteIcon);
+		putValue(NAME, "Delete");
+		putValue(SHORT_DESCRIPTION, "Delete selected component");
+		putValue(ACCELERATOR_KEY, getKeyStroke(VK_DELETE, 0));
+		setEnabled(false);
+
+		selectionManager.addObserver(new SelectionManagerObserver());
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		WorkflowBundle workflowBundle = selectionManager
+				.getSelectedWorkflowBundle();
+		DataflowSelectionModel dataFlowSelectionModel = selectionManager
+				.getDataflowSelectionModel(workflowBundle);
+		// Get all selected components
+		Set<Object> selectedWFComponents = dataFlowSelectionModel.getSelection();
+		for (Object selectedWFComponent : selectedWFComponents)
+			if (selectedWFComponent instanceof Processor) {
+				Processor processor = (Processor) selectedWFComponent;
+				new RemoveProcessorAction(processor.getParent(), processor,
+						null, editManager, selectionManager).actionPerformed(e);
+			} else if (selectedWFComponent instanceof DataLink) {
+				DataLink dataLink = (DataLink) selectedWFComponent;
+				new RemoveDatalinkAction(dataLink.getParent(), dataLink, null,
+						editManager, selectionManager).actionPerformed(e);
+			} else if (selectedWFComponent instanceof InputWorkflowPort) {
+				InputWorkflowPort port = (InputWorkflowPort) selectedWFComponent;
+				new RemoveDataflowInputPortAction(port.getParent(), port, null,
+						editManager, selectionManager).actionPerformed(e);
+			} else if (selectedWFComponent instanceof OutputWorkflowPort) {
+				OutputWorkflowPort port = (OutputWorkflowPort) selectedWFComponent;
+				new RemoveDataflowOutputPortAction(port.getParent(), port,
+						null, editManager, selectionManager).actionPerformed(e);
+			} else if (selectedWFComponent instanceof ControlLink) {
+				ControlLink controlLink = (ControlLink) selectedWFComponent;
+				new RemoveConditionAction(controlLink.getParent(), controlLink,
+						null, editManager, selectionManager).actionPerformed(e);
+			}
+	}
+
+	/**
+	 * Check if action should be enabled or disabled and update its status.
+	 */
+	public void updateStatus(WorkflowBundle selectionWorkflowBundle) {
+		if (selectionWorkflowBundle != null) {
+			DataflowSelectionModel selectionModel = selectionManager
+					.getDataflowSelectionModel(selectionWorkflowBundle);
+			Set<Object> selection = selectionModel.getSelection();
+			if (!selection.isEmpty()) {
+				// Take the first selected item - we only support single selections anyway
+				Object selected = selection.toArray()[0];
+				if ((selected instanceof Processor)
+						|| (selected instanceof InputWorkflowPort)
+						|| (selected instanceof OutputWorkflowPort)
+						|| (selected instanceof DataLink)
+						|| (selected instanceof ControlLink)) {
+					setEnabled(true);
+					return;
+				}
+			}
+		}
+		setEnabled(false);
+	}
+
+	/**
+	 * Observes events on workflow Selection Manager, i.e. when a workflow node
+	 * is selected in the graph view, and enables/disables this action
+	 * accordingly.
+	 */
+	private final class DataflowSelectionObserver extends
+			SwingAwareObserver<DataflowSelectionMessage> {
+		@Override
+		public void notifySwing(Observable<DataflowSelectionMessage> sender,
+				DataflowSelectionMessage message) {
+			updateStatus(selectionManager.getSelectedWorkflowBundle());
+		}
+	}
+
+	private final class SelectionManagerObserver extends
+			SwingAwareObserver<SelectionManagerEvent> {
+		@Override
+		public void notifySwing(Observable<SelectionManagerEvent> sender,
+				SelectionManagerEvent message) {
+			if (!(message instanceof WorkflowBundleSelectionEvent))
+				return;
+			WorkflowBundleSelectionEvent workflowBundleSelectionEvent = (WorkflowBundleSelectionEvent) message;
+			WorkflowBundle oldFlow = workflowBundleSelectionEvent
+					.getPreviouslySelectedWorkflowBundle();
+			WorkflowBundle newFlow = workflowBundleSelectionEvent
+					.getSelectedWorkflowBundle();
+
+			/*
+			 * Remove the workflow selection model listener from the previous
+			 * (if any) and add to the new workflow (if any)
+			 */
+			if (oldFlow != null)
+				selectionManager.getDataflowSelectionModel(oldFlow)
+						.removeObserver(workflowSelectionObserver);
+
+			// Update the buttons status as current dataflow has changed
+			updateStatus(newFlow);
+
+			if (newFlow != null)
+				selectionManager.getDataflowSelectionModel(newFlow)
+						.addObserver(workflowSelectionObserver);
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/RenameWFInputOutputProcessorAction.java
----------------------------------------------------------------------
diff --git a/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/RenameWFInputOutputProcessorAction.java b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/RenameWFInputOutputProcessorAction.java
new file mode 100644
index 0000000..f56a0e0
--- /dev/null
+++ b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/actions/RenameWFInputOutputProcessorAction.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * 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.views.graph.actions;
+
+import static java.awt.event.KeyEvent.VK_F2;
+import static javax.swing.JOptionPane.WARNING_MESSAGE;
+import static javax.swing.JOptionPane.showMessageDialog;
+import static javax.swing.KeyStroke.getKeyStroke;
+
+import java.awt.event.ActionEvent;
+import java.util.Set;
+
+import javax.swing.AbstractAction;
+
+import net.sf.taverna.t2.lang.observer.Observable;
+import net.sf.taverna.t2.lang.observer.Observer;
+import net.sf.taverna.t2.lang.observer.SwingAwareObserver;
+import net.sf.taverna.t2.ui.menu.DesignOnlyAction;
+import net.sf.taverna.t2.workbench.design.actions.EditDataflowInputPortAction;
+import net.sf.taverna.t2.workbench.design.actions.EditDataflowOutputPortAction;
+import net.sf.taverna.t2.workbench.design.actions.RenameProcessorAction;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.icons.WorkbenchIcons;
+import net.sf.taverna.t2.workbench.selection.DataflowSelectionModel;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import net.sf.taverna.t2.workbench.selection.events.DataflowSelectionMessage;
+import net.sf.taverna.t2.workbench.selection.events.SelectionManagerEvent;
+import net.sf.taverna.t2.workbench.selection.events.WorkflowBundleSelectionEvent;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.core.Processor;
+import uk.org.taverna.scufl2.api.port.InputWorkflowPort;
+import uk.org.taverna.scufl2.api.port.OutputWorkflowPort;
+
+/**
+ * An action that allows user to rename workflow input, output or
+ * processor, in case one of these is currently selected in the Graph View.
+ *
+ * @author Alex Nenadic
+ */
+@SuppressWarnings("serial")
+public class RenameWFInputOutputProcessorAction extends AbstractAction implements DesignOnlyAction {
+	/** Current workflow's selection model event observer.*/
+	private Observer<DataflowSelectionMessage> workflowSelectionObserver = new DataflowSelectionObserver();
+
+	private final EditManager editManager;
+	private final SelectionManager selectionManager;
+
+	public RenameWFInputOutputProcessorAction(EditManager editManager,
+			final SelectionManager selectionManager) {
+		super();
+		this.editManager = editManager;
+		this.selectionManager = selectionManager;
+		putValue(SMALL_ICON, WorkbenchIcons.renameIcon);
+		putValue(NAME, "Rename");
+		putValue(SHORT_DESCRIPTION, "Rename inputs, outputs or services");
+		putValue(ACCELERATOR_KEY, getKeyStroke(VK_F2, 0));
+		setEnabled(false);
+
+		selectionManager.addObserver(new SelectionManagerObserver());
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		WorkflowBundle workflowBundle = selectionManager
+				.getSelectedWorkflowBundle();
+		DataflowSelectionModel dataFlowSelectionModel = selectionManager
+				.getDataflowSelectionModel(workflowBundle);
+		// Get selected port
+		Set<Object> selectedWFComponents = dataFlowSelectionModel
+				.getSelection();
+		if (selectedWFComponents.size() > 1) {
+			showMessageDialog(
+					null,
+					"Only one workflow component should be selected for this action.",
+					"Warning", WARNING_MESSAGE);
+		} else {
+			Object selectedWFComponent = selectedWFComponents.toArray()[0];
+			if (selectedWFComponent instanceof InputWorkflowPort) {
+				InputWorkflowPort port = (InputWorkflowPort) selectedWFComponent;
+				new EditDataflowInputPortAction(port.getParent(), port, null,
+						editManager, selectionManager).actionPerformed(e);
+			} else if (selectedWFComponent instanceof OutputWorkflowPort) {
+				OutputWorkflowPort port = (OutputWorkflowPort) selectedWFComponent;
+				new EditDataflowOutputPortAction(port.getParent(), port, null,
+						editManager, selectionManager).actionPerformed(e);
+			} else if (selectedWFComponent instanceof Processor) {
+				Processor processor = (Processor) selectedWFComponent;
+				new RenameProcessorAction(processor.getParent(), processor,
+						null, editManager, selectionManager).actionPerformed(e);
+			} else { // should not happen as the button will be disabled otherwise, but ...
+				showMessageDialog(
+						null,
+						"This action does not apply for the selected component.",
+						"Warning", WARNING_MESSAGE);
+			}
+		}
+	}
+
+	/**
+	 * Check if action should be enabled or disabled and update its status.
+	 */
+	public void updateStatus() {
+		WorkflowBundle workflowBundle = selectionManager
+				.getSelectedWorkflowBundle();
+		DataflowSelectionModel selectionModel = selectionManager
+				.getDataflowSelectionModel(workflowBundle);
+
+		// List of all selected objects in the graph view
+		Set<Object> selection = selectionModel.getSelection();
+
+		if (!selection.isEmpty()) {
+			// Take the first selected item - we only support single selections anyway
+			Object selected = selection.toArray()[0];
+			if ((selected instanceof Processor)
+					|| (selected instanceof InputWorkflowPort)
+					|| (selected instanceof OutputWorkflowPort)) {
+				setEnabled(true);
+				return;
+			}
+		}
+		setEnabled(false);
+	}
+
+	/**
+	 * Observes events on workflow Selection Manager, i.e. when a workflow node
+	 * is selected in the graph view, and enables/disables this action
+	 * accordingly.
+	 */
+	private final class DataflowSelectionObserver extends
+			SwingAwareObserver<DataflowSelectionMessage> {
+		@Override
+		public void notifySwing(Observable<DataflowSelectionMessage> sender,
+				DataflowSelectionMessage message) {
+			updateStatus();
+		}
+	}
+
+	private final class SelectionManagerObserver extends
+			SwingAwareObserver<SelectionManagerEvent> {
+		@Override
+		public void notifySwing(Observable<SelectionManagerEvent> sender,
+				SelectionManagerEvent message) {
+			if (!(message instanceof WorkflowBundleSelectionEvent))
+				return;
+			WorkflowBundleSelectionEvent workflowBundleSelectionEvent = (WorkflowBundleSelectionEvent) message;
+			WorkflowBundle oldFlow = workflowBundleSelectionEvent
+					.getPreviouslySelectedWorkflowBundle();
+			WorkflowBundle newFlow = workflowBundleSelectionEvent
+					.getSelectedWorkflowBundle();
+			// Update the buttons status as current dataflow has changed
+			updateStatus();
+
+			/*
+			 * Remove the workflow selection model listener from the previous
+			 * (if any) and add to the new workflow (if any)
+			 */
+			if (oldFlow != null)
+				selectionManager.getDataflowSelectionModel(oldFlow)
+						.removeObserver(workflowSelectionObserver);
+
+			if (newFlow != null)
+				selectionManager.getDataflowSelectionModel(newFlow)
+						.addObserver(workflowSelectionObserver);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/config/GraphViewConfiguration.java
----------------------------------------------------------------------
diff --git a/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/config/GraphViewConfiguration.java b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/config/GraphViewConfiguration.java
new file mode 100644
index 0000000..b1c3265
--- /dev/null
+++ b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/config/GraphViewConfiguration.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (C) 2009 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.views.graph.config;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import uk.org.taverna.configuration.AbstractConfigurable;
+import uk.org.taverna.configuration.ConfigurationManager;
+
+import net.sf.taverna.t2.workbench.models.graph.Graph.Alignment;
+import net.sf.taverna.t2.workbench.models.graph.GraphController.PortStyle;
+
+/**
+ * Configuration for the GraphViewComponent.
+ * 
+ * @author David Withers
+ */
+public class GraphViewConfiguration extends AbstractConfigurable {
+	public static final String PORT_STYLE = "portStyle";
+	public static final String ALIGNMENT = "alignment";
+	public static final String ANIMATION_ENABLED = "animationEnabled";
+	public static final String ANIMATION_SPEED = "animationSpeed";
+
+	private Map<String, String> defaultPropertyMap;
+
+	public GraphViewConfiguration(ConfigurationManager configurationManager) {
+		super(configurationManager);
+	}
+
+	@Override
+	public String getCategory() {
+		return "general";
+	}
+
+	@Override
+	public Map<String, String> getDefaultPropertyMap() {
+		if (defaultPropertyMap == null) {
+			defaultPropertyMap = new HashMap<>();
+			defaultPropertyMap.put(PORT_STYLE, PortStyle.NONE.toString());
+			defaultPropertyMap.put(ALIGNMENT, Alignment.VERTICAL.toString());
+			defaultPropertyMap.put(ANIMATION_ENABLED, "false");
+			defaultPropertyMap.put(ANIMATION_SPEED, "800");
+		}
+		return defaultPropertyMap;
+	}
+
+	@Override
+	public String getDisplayName() {
+		return "Diagram";
+	}
+
+	@Override
+	public String getFilePrefix() {
+		return "Diagram";
+	}
+
+	@Override
+	public String getUUID() {
+		return "3686BA31-449F-4147-A8AC-0C3F63AFC68F";
+	}
+}