diff --git a/Kieker.WebGUI/lib/kieker-1.6-SNAPSHOT_emf.jar b/Kieker.WebGUI/lib/kieker-1.6-SNAPSHOT_emf.jar
index 602b5194f4809d48124453bbefdc43664cc4974d..177ced9bf680c39239073c4a3ba63fbd87e65ac1 100644
Binary files a/Kieker.WebGUI/lib/kieker-1.6-SNAPSHOT_emf.jar and b/Kieker.WebGUI/lib/kieker-1.6-SNAPSHOT_emf.jar differ
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorBean.java
index fd83efb10ddae607ccfa663525a8b2202a0d128e..9f4e7f69908be5b3e76ed830089a426460fdd00c 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorBean.java
@@ -57,6 +57,7 @@ import kieker.analysis.plugin.AbstractPlugin;
 import kieker.analysis.plugin.annotation.InputPort;
 import kieker.analysis.plugin.annotation.OutputPort;
 import kieker.analysis.plugin.annotation.Plugin;
+import kieker.analysis.plugin.annotation.Property;
 import kieker.analysis.plugin.annotation.RepositoryPort;
 import kieker.analysis.plugin.filter.AbstractFilterPlugin;
 import kieker.analysis.plugin.reader.AbstractReaderPlugin;
@@ -533,6 +534,34 @@ public final class CurrentAnalysisEditorBean {
 		}
 	}
 
+	public List<Property> getProperties(final Class<?> clazz) {
+		final ArrayList<Property> result = new ArrayList<Property>();
+
+		// Get the two potential annotations
+		final Plugin annotationPlugin = clazz.getAnnotation(Plugin.class);
+		final Repository annotationRepository = clazz.getAnnotation(Repository.class);
+
+		final Property[] properties;
+
+		// Now check which one of them is available
+		if ((annotationPlugin == null) || annotationPlugin.description().isEmpty()) {
+			if ((annotationRepository == null) || annotationRepository.description().isEmpty()) {
+				// None.
+				properties = new Property[0];
+			} else {
+				properties = annotationRepository.configuration();
+			}
+		} else {
+			properties = annotationPlugin.configuration();
+		}
+
+		for (final Property property : properties) {
+			result.add(property);
+		}
+
+		return result;
+	}
+
 	/**
 	 * Searches for input ports within the given class and returns them.
 	 * 
diff --git a/Kieker.WebGUI/src/main/webapp/AnalysisEditor.xhtml b/Kieker.WebGUI/src/main/webapp/AnalysisEditor.xhtml
index b3a205bd7b3a934f1ec70648bd6f04cbc035b92a..75e76745660ef3d730c458efa4de72833f192231 100644
--- a/Kieker.WebGUI/src/main/webapp/AnalysisEditor.xhtml
+++ b/Kieker.WebGUI/src/main/webapp/AnalysisEditor.xhtml
@@ -25,26 +25,34 @@
         <script language="javascript" type="text/javascript" src="../js/jit.js"></script>
         <script language="javascript" type="text/javascript" src="../js/flowEditor.js"></script>
 
-        <script>
-            window.onload = function() {
-                document.getElementById('hidden:link').onclick();
-            }
-            
+        <script>            
             nodeClickListener = function(node, info, e) {
                 nodeClickCommand([{name : 'ID', value : node.id}, {name : 'type', value : node.data.$nodeType}]);
+               // var graphNode = graph.getNode(node.id);
+               // graphNode.name = 'Hallo, Welt';
+               // graph.refresh();
             }
             
             nodeRemoveListener = function(node, info, e) {
                 nodeRemoveCommand([{name : 'ID', value : node.id}, {name : 'type', value : node.data.$nodeType}]);
             }
+            
+            edgeCreateListener = function(sourceNodeID, targetNodeID, sourcePortID, targetPortID) {
+                
+            }
+            
+            edgeRemoveListener = function(sourceNodeID, targetNodeID, sourcePortID, targetPortID) {
+                
+            }
+            
+            nodeMouseListener = function(node, info, e) {
+            }
         </script>
     </h:head>
 
     <h:body>        
         <h:form id="hidden" style="display:none">
-            <h:commandLink id="link">
-                <f:ajax event="click" listener="#{currentAnalysisEditorBean.initializeGraph()}" />
-            </h:commandLink>
+            <p:remoteCommand autoRun="true" name="init" action="#{currentAnalysisEditorBean.initializeGraph()}" />
         </h:form>
         <h:form id="hiddenNodeProperties" style="display:none"> 
             <p:remoteCommand name="nodeClickCommand" action="#{currentAnalysisEditorBean.nodeClicked()}" update=":propertiesForm"/>
@@ -157,6 +165,10 @@
                                     <p:dataList value="#{currentAnalysisEditorBean.getRepositoryPorts(reader)}" var="port">
                                         #{port.name()}
                                     </p:dataList>
+                                    <b><h:outputText value="Configuration:"/></b>
+                                    <p:dataList value="#{currentAnalysisEditorBean.getProperties(reader)}" var="property">
+                                        #{property.name()}
+                                    </p:dataList>
                                 </p:tooltip>
                             </ui:repeat>
                         </p:tab>
@@ -180,6 +192,10 @@
                                     <p:dataList value="#{currentAnalysisEditorBean.getRepositoryPorts(filter)}" var="port">
                                         #{port.name()}
                                     </p:dataList>
+                                    <b><h:outputText value="Configuration:"/></b>
+                                    <p:dataList value="#{currentAnalysisEditorBean.getProperties(filter)}" var="property">
+                                        #{property.name()}
+                                    </p:dataList>
                                 </p:tooltip>                                
                             </ui:repeat>
                         </p:tab>
@@ -190,6 +206,11 @@
                                     <b><h:outputText value="#{repository.simpleName} (#{repository.name})"/></b>
                                     <br/>
                                     <h:outputText value="#{currentAnalysisEditorBean.getDescription(repository)}"/>
+                                    <br/><br/>
+                                    <b><h:outputText value="Configuration:"/></b>
+                                    <p:dataList value="#{currentAnalysisEditorBean.getProperties(repository)}" var="property">
+                                        #{property.name()}
+                                    </p:dataList>
                                 </p:tooltip>  
                             </ui:repeat>
                         </p:tab>
diff --git a/Kieker.WebGUI/src/main/webapp/js/flowEditor.js b/Kieker.WebGUI/src/main/webapp/js/flowEditor.js
index b411673eb0ca53b8c2d6e20bb1ff189efe263c76..de8e6511bdd91e0f42912ad6cbddb06492983bab 100644
--- a/Kieker.WebGUI/src/main/webapp/js/flowEditor.js
+++ b/Kieker.WebGUI/src/main/webapp/js/flowEditor.js
@@ -114,6 +114,157 @@ function GraphFlow(){
 	//				FUNCTIONS				   //
 	/////////////////////////////////////////////
 
+	
+	/**
+	Sets the mouseCursor to a new one. If the new cursor is null,
+	it will be reset to the default mouse cursor.
+	*/
+	this.setMouseCursor = function(newCursor){
+		if(newCursor == null){
+			fd.canvas.getElement().style.cursor = '';
+		}else{
+			fd.canvas.getElement().style.cursor = newCursor;
+		}
+	}
+	
+	this.graphToDot = function(filename){
+		var node;
+		var dotGraph = 'digraph structs {\nnode [shape=plaintext];\n\n'
+		for(var n=0; n < json.length; n++){
+			node = json[n];
+			if(node.data.$type == "nodeFamily"){
+				dotGraph += nodeToDot(node);
+				dotGraph += '\n';
+			}
+		}
+		dotGraph += '}';
+		console.log(dotGraph);
+	}
+	
+	/**
+		Converts a single node to a node in dot language, and returns it as a string.
+		@param nodeFamily - the node which is to be converted
+	*/
+	this.nodeToDot = function(nodeFamily){
+		var pWidth = (nodeFamily.data.$width+vertexLabelSize)/2;
+		var tableDef = '<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1" CELLPADDING="0">\n',
+			portDefA = '<TR><TD WIDTH="'+pWidth+'" FIXEDSIZE="true" HEIGHT="'+(2*vertexLabelSize)+'" PORT="',
+			portDefB = '">p</TD></TR>\n',
+			padDefA = '<TR><TD FIXEDSIZE="true" WIDTH="'+pWidth+'" HEIGHT="',
+			padDefB = '"></TD></TR>\n',
+			emptyDef = '<TD FIXEDSIZE="true" HEIGHT="1" WIDTH="'+pWidth+'"></TD>\n';
+		
+		// this variable will contain a string, representing a node in dot-code
+		var dot = nodeFamily.id,
+			dotEdges = '';
+		
+		dot+= ' [label=< '+tableDef;
+		dot+= '<TR><TD COLSPAN="2" HEIGHT="'+(2.5*vertexLabelSize)+'"></TD></TR><TR>\n';
+		
+		var portIndex = nodeFamily.data.$jsonIndex+2,
+			lastPortIndex = nodeFamily.data.$jsonIndex+1+ nodeFamily.data.$portCount;
+		var port = json[portIndex];
+		if(port.data.$type == "inputPort"){
+			
+			dot += '<TD>'+tableDef;
+			var dotInput = '',
+				countInput = 0;
+			
+			// write the dot representation of ports into a temporary string
+			while(portIndex <= lastPortIndex && port.data.$type == "inputPort"){
+				dotInput += portDefA+ port.id + portDefB;
+				countInput++;
+				portIndex++;
+				port = json[portIndex];
+			}
+			
+			// apply padding if there is space above and below the ports
+			var padding = nodeFamily.data.$height/2 - (1.5+countInput)*vertexLabelSize;
+			if(padding > 0){
+				dotInput = padDefA+padding+padDefB + dotInput + padDefA+padding+padDefB;
+			}
+			
+			// append temp string to result
+			dot += dotInput + '</TABLE></TD>';
+		}
+		else{
+			dot += emptyDef;
+		}
+		
+		if (portIndex <= lastPortIndex){
+			// we get here if there were no input ports OR if we handled them all
+			var dotRight = '',
+				countRight = 0,
+				adja,			// outgoing edges of port
+				adjaIter;		// used to iterate through the edges
+				
+			// add repository ports
+			if(port.data.$type == "repositoryPort"){
+				
+				dot += '<TD>'+tableDef;
+				
+				// write the dot representation of ports into a temporary string
+				while(portIndex <= lastPortIndex && port.data.$type == "repositoryPort"){
+					dotRight += portDefA+ port.id + portDefB;
+					
+					// add edges
+					adja = port.adjacencies;
+					for(a = 0; a < adja.length; a++){
+						adjaIter = adja[a];
+						dotEdges += nodeFamily.id+":"+port.id + ":e->" + adjaIter.data.$targetFamily + ":" + adjaIter.nodeTo+":w;\n";
+					}
+					
+					countRight++;
+					portIndex++;
+					port = json[portIndex];
+				}
+			}
+			// add output ports
+			if(portIndex <= lastPortIndex && port.data.$type == "outputPort"){
+				
+				// if we have preceding repo ports, insert a little gap to separate
+				// the output ports
+				if(json[portIndex-1].data.$type == "repositoryPort"){
+					dotRight += padDefA + vertexLabelSize + padDefB;
+					countRight += 0.5;
+				}
+				else{
+					dot += '<TD>'+tableDef;
+				}
+				
+				// write the dot representation of ports into a temporary string
+				while(portIndex <= lastPortIndex && port.data.$type == "outputPort"){
+					dotRight += portDefA+ port.id + portDefB;
+					
+					// add edges
+					adja = port.adjacencies;
+					for(var a = 0; a < adja.length; a++){
+						adjaIter = adja[a];
+						dotEdges += nodeFamily.id+":"+port.id + ":e->" + adjaIter.data.$targetFamily + ":" + adjaIter.nodeTo+":w;\n";
+					}
+					
+					countRight++;
+					portIndex++;
+					port = json[portIndex];
+				}
+			} 
+			// apply padding  to right sideif there is space above and below the ports
+				var padding = nodeFamily.data.$height/2 - (1.5+countRight)*vertexLabelSize;
+				if(padding > 0){
+					dotRight = padDefA+padding+padDefB + dotRight + padDefA+padding+padDefB;
+				}
+				dot += dotRight + '</TABLE></TD>';
+		}else{
+			dot += emptyDef;
+		}
+		// end of ports
+		
+		dot+= '</TR><TR><TD COLSPAN="2" HEIGHT="'+vertexLabelSize/2+'"></TD></TR></TABLE>>];\n';
+		dot+= dotEdges;
+		
+		return dot;
+	}
+	
 	/** 
 		reloads the graph, trying to restore all positions 
 		this function needs to be called whenever nodes or egdges are
@@ -152,11 +303,6 @@ function GraphFlow(){
 		if(listener[event] == undefined){
 			listener[event] = [];
 		}
-		/*if(listenerFunction.arguments.length != 3){
-			Log.write("Invalid Listener Function: needs 3 parameters");
-			return;
-		}*/
-		// push new function to the listener table
 		listener[event].push(listenerFunction);
 	}
 	
@@ -319,7 +465,7 @@ function GraphFlow(){
 	 @param inputPortIDs - an array of properties for the input ports (id, name, tooltip)
 	 @param outputPortIDs - an array of properties for the output ports (id, name, tooltip)
 	 */
-	function addNode(xPosition, yPosition, nodeFamily, repositoryPorts, inputPorts, outputPorts, nodeType){
+	this.addNode = function(xPosition, yPosition, nodeFamily, repositoryPorts, inputPorts, outputPorts, nodeType){
 	
 	var countRepo = 0,
 		countInput = 0,
@@ -335,15 +481,16 @@ function GraphFlow(){
 		countOutput= outputPorts.length;
 	}
 	
-	var maxPorts = Math.max(countInput, countRepo+countOutput),
+	var maxPorts = Math.max(countInput, countRepo+countOutput+0.5),
 		size = vertexLabelSize*2;
-		
-	if(maxPorts >= countInput && countRepo > 0 && countInput > 0){
-		maxPorts++;
+	
+	// insert some space between repo ports and output ports, only if both are present
+	if(maxPorts > countInput && (countRepo == 0 || countOutput == 0)){
+		maxPorts-= 0.5;
 	}
 		
 	var width = (nodeFamily.name.length+4)*vertexLabelSize,
-		height = 1*size + 
+		height = size + 
 			Math.max( 2*size, size/2 + maxPorts * size);
 	
 	// the classname may be longer than the diplayed name
@@ -403,27 +550,31 @@ function GraphFlow(){
 		var x, y, relativeX, relativeY,
 			loopPorts, loopType;
 		switch(portType){
-			case 0: // repository ports
-				var repoSpace = 0;
-				if(countInput == 0){
-					repoSpace = 1;
+			case 0: // input ports
+				relativeX = -width/2;
+				relativeY = (0.75 - countInput/2 )*size;
+				loopPorts = inputPorts;
+				loopType = "inputPort";
+				break;
+		
+			case 1: // repository ports
+				var repoSpace = 0.5;
+				if(countOutput == 0){
+					repoSpace = 0;
 				}
-				relativeX = width/2,
-				relativeY = ((0.5+repoSpace-countOutput-countRepo) * size)/2,
+				relativeX = width/2;
+				relativeY = (0.75 - (countOutput+countRepo+repoSpace)/2 )*size;
 				loopPorts = repositoryPorts;
 				loopType = "repositoryPort";
 				break;
 				
-			case 1: // input ports
-				relativeX = -width/2,
-				relativeY = ( (1.5-countInput)*size)/2,
-				loopPorts = inputPorts;
-				loopType = "inputPort";
-				break;
-				
 			case 2: // output ports
-				relativeX = width/2,
-				relativeY = ((1.5 + countRepo - countOutput) * size)/2;
+				var repoSpace = 0.5;
+				if(countRepo == 0){
+					repoSpace = 0;
+				}
+				relativeX = width/2;
+				relativeY = (0.75 - (countOutput-countRepo-repoSpace)/2 )*size;
 				loopPorts = outputPorts;
 				loopType = "outputPort";
 				break;
@@ -588,7 +739,8 @@ function GraphFlow(){
 		var edge ={
 				  "nodeTo": targetID, 
 				  "nodeFrom": sourceID,
-				  "data": {"$direction" : [ sourceID, targetID ] }
+				  "data": {"$direction" : [ sourceID, targetID ],
+						   "$targetFamily" : targetFamilyID}
 				  };
 				  
 		adja.push(edge);
@@ -1110,7 +1262,7 @@ function init(){
 	// add a new listener: 
 	graph.addListener("onRightClick", function(node,info,e){
 										var newNode = {"id":"nuNode"+addNodeCounter, 
-														"name":"i am node #"+addNodeCounter, 
+														"name":"node #"+addNodeCounter, 
 														"nodeClass":"someClassAgain",
 														"tooltip":"i am new and shiny!"};
 										graph.addFilter(info.getPos().x, info.getPos().y, newNode, null,
@@ -1119,16 +1271,19 @@ function init(){
 										graph.refresh();
 										addNodeCounter++;
 					  });
-					  
+	/*graph.addListener("onRightClick", function(node, info, e){
+			graph.graphToDot(null);
+	});*/	
+	
 	// adds a listener that removes invalid Edges
 	graph.addEdgeConstraints();
 	
-	graph.addListener("onRemoveNode", function(nodeID){alert("bye bye, "+ nodeID+".");});
+	//graph.addListener("onRemoveNode", function(nodeID){alert("bye bye, "+ nodeID+".");});
 	
 	// define graph by adding nodes
 	var node1 = {"id":"superNode1", 
 					  "name":"i am node", 
-					  "nodeClass":"someClass",
+					  "nodeClass":"someFilter",
 					  "tooltip":"look at me, i'm a node!"};
 	
 	graph.addFilter(0, -100, node1,[{"name":"repoPort", "id":"rp1", "tooltip":"repo"},
@@ -1149,15 +1304,13 @@ function init(){
 	
 	// add nodes after graph creation
 	var node2 = {"id":"superNode2", 
-					  "name":"i am node", 
-					  "nodeType":"Filter",
-					  "nodeClass":"someOtherClass",
+					  "name":"Super Repo", 
+					  "nodeClass":"Reposiotry",
 					  "tooltip":"look at me, i'm another node!"};
-	graph.addRepository(100, 0, node2,{"name":"outputPort", "id":"op1"});
+	graph.addRepository(100, 0, node2,{"name":"inputPort", "id":"ip1"});
 	var node3 = {"id":"superNode3", 
 					  "name":"i am reader", 
-					  "nodeType":"Reader",
-					  "nodeClass":"someOtherClass",
+					  "nodeClass":"Reader",
 					  "tooltip":"look at me, i'm another node!"};
 	graph.addReader(0, 100, node3,[{"name":"repoPort", "id":"rp1"}], [{"name":"outputPort", "id":"op1"}]);
 	// refresh graph to show the new nodes
diff --git a/Kieker.WebGUI/src/main/webapp/js/jit.js b/Kieker.WebGUI/src/main/webapp/js/jit.js
index ccb742b49bf747caf95c1e04b80f55a9147d3eec..02ffca3052eb09a17676669aedf4c988896c0139 100644
--- a/Kieker.WebGUI/src/main/webapp/js/jit.js
+++ b/Kieker.WebGUI/src/main/webapp/js/jit.js
@@ -6196,6 +6196,88 @@ var NodeHelper = {
     'contains': function(npos, pos, dim) {
       return NodeHelper.circle.contains(npos, pos, dim);
     }
+  },
+  /*
+  Object: NodeHelper.roundRect
+  */
+  'roundRect': {
+    /*
+    Method: render
+    
+    Renders a rounded rectangle into the canvas.
+    
+    Parameters:
+    
+    type - (string) Possible options are 'fill' or 'stroke'.
+    pos - (object) An *x*, *y* object with the position of the center of the rectangle.
+    width - (number) The width of the rectangle.
+    height - (number) The height of the rectangle.
+	roundness - the radius of the rounded corners.
+    canvas - (object) A <Canvas> instance.
+    
+    Example:
+    (start code js)
+    NodeHelper.rectangle.render('fill', { x: 10, y: 30 }, 30, 40, viz.canvas);
+    (end code)
+    */
+    'render': function(type, pos, width, height, roundness, canvas){
+		width/=2;
+		height/=2;
+		var ctx = canvas.getCtx(),
+			rWidth = width - roundness,
+			rHeight = height - roundness;
+			x = pos.x - rWidth,
+			y = pos.y - rHeight;
+		ctx.save();
+	  
+		var pif = Math.PI/2;
+		ctx.beginPath();
+		// upper left
+		ctx.arc(x , y , roundness, Math.PI, 3*pif, false);
+		x = pos.x + rWidth,
+		ctx.lineTo(x, pos.y - height);
+
+		// upper right
+		ctx.arc(x , y , roundness, 3*pif, 0, false);
+		y = pos.y + rHeight,
+		ctx.lineTo(pos.x + width, y);
+
+		// lower right
+		ctx.arc(x , y , roundness,0, pif, false);
+		x = pos.x - rWidth,
+		ctx.lineTo(x, pos.y + height);
+
+		// lower left
+		ctx.arc(x , y , roundness, pif, Math.PI, false);
+		ctx.closePath();
+
+		ctx[type]();
+		ctx.restore();
+		
+		width*=2;
+		height*=2;
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    npos - (object) An *x*, *y* object with the <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    width - (number) The width of the rendered rectangle.
+    height - (number) The height of the rendered rectangle.
+    
+    Example:
+    (start code js)
+    NodeHelper.rectangle.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30, 40);
+    (end code)
+    */
+    'contains': function(npos, pos, width, height){
+      return Math.abs(pos.x - npos.x) <= width / 2
+          && Math.abs(pos.y - npos.y) <= height / 2;
+    }
   }
 };
 
@@ -6387,7 +6469,8 @@ var EdgeHelper = {
     },
     /*
     Method: contains
-    
+	
+    Simply copied from rectangle.
     Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
     
     Parameters:
@@ -17622,6 +17705,7 @@ $jit.FlowGraph.$extend = true;
 	    	        var pos = node.pos.getc(true), 
 						width = node.getData('width'),
 						height = node.getData('height'),
+						rounded = node.getData('dim')/4,
 						strokeWidth = 2,
 						fillColor = node.getData('fillColor'),
 						posX = pos.x ,
@@ -17629,11 +17713,11 @@ $jit.FlowGraph.$extend = true;
 					var	ctx = canvas.getCtx();
 						
 					// draw Stroke ( in the color, specified in node properties)
-					this.nodeHelper.rectangle.render('fill', {x: posX, y: posY}, width+2*strokeWidth, height+2*strokeWidth, canvas); 
+					this.nodeHelper.roundRect.render('fill', {x: posX, y: posY}, width+2*strokeWidth, height+2*strokeWidth, rounded+2, canvas); 
 					
 					// fill box
 					ctx.fillStyle = fillColor;
-	    	       	this.nodeHelper.rectangle.render('fill', {x: posX, y: posY}, width, height, canvas);  
+	    	       	this.nodeHelper.roundRect.render('fill', {x: posX, y: posY}, width, height, rounded, canvas);  
 	    	      },
 				  
 	    	      'contains': function(node, pos){
@@ -17664,7 +17748,7 @@ $jit.FlowGraph.$extend = true;
 	    	            ctx = canvas.getCtx();
 					
 					// draw close-button area
-					this.nodeHelper.square.render('fill', {x: bx, y: by}, size, canvas);
+					this.nodeHelper.roundRect.render('fill', {x: bx, y: by}, size*2, size*2, size/2, canvas);
 					
 					// draw cross
 					var yTop = by-4*pe,