diff --git a/Kieker.WebGUI/bin/data/Timer-Counter-Example/Timer-Counter-Example.kax b/Kieker.WebGUI/bin/data/Timer-Counter-Example/Timer-Counter-Example.kax
index 4430926057a278957a0981ffdba4f98ccb88c87f..55b94b5acb4a6af2edb4bd7dc1a7eb20e15b3e04 100644
--- a/Kieker.WebGUI/bin/data/Timer-Counter-Example/Timer-Counter-Example.kax
+++ b/Kieker.WebGUI/bin/data/Timer-Counter-Example/Timer-Counter-Example.kax
@@ -19,7 +19,7 @@
     <outputPorts name="relayedEvents"/>
     <inputPorts name="receivedEvents"/>
   </plugins>
-  <plugins xsi:type="Filter" name="CountingFilter" classname="kieker.analysis.plugin.filter.forward.CountingFilter">
+  <plugins xsi:type="Filter" name="Timestamp Records Counter" classname="kieker.analysis.plugin.filter.forward.CountingFilter">
     <outputPorts name="relayedEvents" subscribers="//@plugins.2/@inputPorts.0"/>
     <outputPorts name="currentEventCount"/>
     <displays name="Visual Counter Display"/>
@@ -27,7 +27,7 @@
     <displays name="Plot Counter Display"/>
     <inputPorts name="inputEvents"/>
   </plugins>
-  <plugins xsi:type="Filter" name="CountingFilter" classname="kieker.analysis.plugin.filter.forward.CountingFilter">
+  <plugins xsi:type="Filter" name="Timestamps Counter" classname="kieker.analysis.plugin.filter.forward.CountingFilter">
     <outputPorts name="relayedEvents" subscribers="//@plugins.1/@inputPorts.0"/>
     <outputPorts name="currentEventCount"/>
     <displays name="Visual Counter Display"/>
@@ -36,9 +36,15 @@
     <inputPorts name="inputEvents"/>
   </plugins>
   <views name="Counter View" description="No description available.">
-    <displayConnectors name="Visual Display" display="//@plugins.3/@displays.0"/>
-    <displayConnectors name="Text Display" display="//@plugins.3/@displays.1"/>
-    <displayConnectors name="Plot Display" display="//@plugins.3/@displays.2"/>
+    <displayConnectors name="Timestamp Records (Image)" display="//@plugins.3/@displays.0"/>
+    <displayConnectors name="Timestamp Records (Text)" display="//@plugins.3/@displays.1"/>
+    <displayConnectors name="Timestamp Records (Plot)" display="//@plugins.3/@displays.2"/>
+    <displayConnectors name="Timestamps (Image)" display="//@plugins.4/@displays.0"/>
+    <displayConnectors name="Timestamps (Text)" display="//@plugins.4/@displays.1"/>
+    <displayConnectors name="Timestamps (Plot)" display="//@plugins.4/@displays.2"/>
+  </views>
+  <views name="Only Records View" description="No description available.">
+    <displayConnectors name="Timestamp Records" display="//@plugins.3/@displays.1"/>
   </views>
   <properties name="recordsTimeUnit" value="NANOSECONDS"/>
   <properties name="projectName" value="AnalysisProject"/>
diff --git a/Kieker.WebGUI/bin/data/Timer-Counter-Example/meta.dat b/Kieker.WebGUI/bin/data/Timer-Counter-Example/meta.dat
index 4641d7d01381126aadc5d85bcc3b6e428230a1a0..eee45730dda6dfb68f026950f30b92599155d4d5 100644
--- a/Kieker.WebGUI/bin/data/Timer-Counter-Example/meta.dat
+++ b/Kieker.WebGUI/bin/data/Timer-Counter-Example/meta.dat
@@ -1,5 +1,6 @@
 #
-#Wed May 22 14:54:55 CEST 2013
+#Fri May 31 19:58:26 CEST 2013
 owner=admin
+cockpit\ layout=0 0 0 1 0 2 1 0 1 1 1 2 0 0 
 last\ user=admin
-analysis\ layout=id0 -615 -260 336 72;id1 -675 22 216 84;id2 -73 -108 204 72;id3 -73 22 204 72;id7 -371 34 264 84;id9 -371 -100 264 84;\#id1.0 id9.21 -535.5 21.5 -535.5 -88.5;id9.22 id2.2 -207.5 -100.5 -207.5 -96.5;
+analysis\ layout=id0 -615 -256 336 72;id1 -675 26 216 84;id2 59 -104 204 72;id3 59 26 204 72;id4 -305 38 396 84;id5 -305 -96 312 84;\#id1.0 id5.9 -535.5 25.5 -535.5 -84.5;id5.10 id2.2 -75.5 -96.5 -75.5 -92.5;
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/utility/Analysis.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/utility/Analysis.java
index 423b559506f73f85f59aa62aa95f1cf74e8dfb78..661e924f93721371d785c3a667cc9618dd5e4b8e 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/utility/Analysis.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/utility/Analysis.java
@@ -102,6 +102,7 @@ public class Analysis {
 				for (final Object displayConnector : displayConnectors) {
 					final Object display = new Mirror().on(displayConnector).invoke().method("getDisplay").withoutArgs();
 					final String displayName = (String) new Mirror().on(display).invoke().method("getName").withoutArgs();
+					final String displayConnectorName = (String) new Mirror().on(displayConnector).invoke().method("getName").withoutArgs();
 					final Object displayParent = new Mirror().on(display).invoke().method("getParent").withoutArgs();
 					final Object plugin = pluginMap.get(displayParent);
 
@@ -111,9 +112,9 @@ public class Analysis {
 						if (displayAnnoation != null) {
 							final String potentialDisplayName = (String) new Mirror().on(displayAnnoation).invoke().method("name").withoutArgs();
 							if (displayName.equals(potentialDisplayName)) {
-								methodMap.put(displayName, method);
-								displayObjectMap.put(displayName, method.getParameterTypes()[0].newInstance());
-								displayPluginMap.put(displayName, plugin);
+								methodMap.put(displayConnectorName, method);
+								displayObjectMap.put(displayConnectorName, method.getParameterTypes()[0].newInstance());
+								displayPluginMap.put(displayConnectorName, plugin);
 								break;
 							}
 						}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitBean.java
index ade0ef8401716c833a13bcdbfb2fe59c84416eaf..e3bd10d2887d2f851c25ba1676c4fdd6951bf6ee 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitBean.java
@@ -16,31 +16,39 @@
 
 package kieker.webgui.web.beans.view;
 
+import java.util.Collection;
 import java.util.List;
 
 import javax.faces.application.Application;
 import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
 import javax.faces.component.html.HtmlOutputText;
 import javax.faces.context.FacesContext;
 
+import kieker.analysis.AnalysisController;
 import kieker.analysis.model.analysisMetaModel.MIDisplayConnector;
 import kieker.analysis.model.analysisMetaModel.MIProject;
 import kieker.analysis.model.analysisMetaModel.MIView;
 import kieker.common.logging.Log;
 import kieker.common.logging.LogFactory;
+import kieker.monitoring.core.registry.Registry;
 import kieker.webgui.common.exception.DisplayNotFoundException;
 import kieker.webgui.common.exception.InvalidAnalysisStateException;
 import kieker.webgui.common.exception.ProjectLoadException;
 import kieker.webgui.service.IProjectService;
 import kieker.webgui.web.beans.application.GlobalPropertiesBean;
 import kieker.webgui.web.beans.application.ProjectsBean;
+import kieker.webgui.web.utility.CockpitLayout;
 
+import org.primefaces.component.chart.line.LineChart;
 import org.primefaces.component.dashboard.Dashboard;
 import org.primefaces.component.panel.Panel;
 import org.primefaces.model.DashboardColumn;
 import org.primefaces.model.DashboardModel;
 import org.primefaces.model.DefaultDashboardColumn;
 import org.primefaces.model.DefaultDashboardModel;
+import org.primefaces.model.chart.CartesianChartModel;
+import org.primefaces.model.chart.LineChartSeries;
 
 import net.vidageek.mirror.dsl.Mirror;
 import net.vidageek.mirror.exception.MirrorException;
@@ -63,6 +71,7 @@ public class CurrentCockpitBean {
 
 	private static final Log LOG = LogFactory.getLog(CurrentCockpitBean.class);
 
+	private static final String ID_PREFIX = "displayConnector_";
 	private static final int NUMBER_COLUMNS = 2;
 
 	private String projectName;
@@ -78,11 +87,38 @@ public class CurrentCockpitBean {
 	@Autowired
 	private GlobalPropertiesBean globalPropertiesBean;
 
+	private CockpitLayout cockpitLayout;
+	private final Registry<MIDisplayConnector> displayConnectors = new Registry<MIDisplayConnector>();
+
 	/**
 	 * Creates a new instance of this class. <b>Do not call this constructor manually. It will only be accessed by Spring.</b>
 	 */
 	public CurrentCockpitBean() {
-		this.createDashboard();
+		// No code necessary
+	}
+
+	/**
+	 * This method initializes the bean by using the current project name to load the project. <b>Do not call this method manually. It will only be accessed by
+	 * Spring.</b>
+	 */
+	public void initalize() {
+		try {
+			// Make sure that the initialization will only be done for the init request.
+			if (!FacesContext.getCurrentInstance().isPostback()) {
+				// Remember the given parameters
+				this.project = this.projectsBean.openProject(this.projectName);
+				this.createDashboard();
+
+				this.cockpitLayout = new CockpitLayout(this.project, this.projectService.getCockpitLayout(this.projectName), NUMBER_COLUMNS);
+			}
+		} catch (final ProjectLoadException ex) {
+			CurrentCockpitBean.LOG.error("An error occured while loading the project.", ex);
+			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectLoadingException());
+		} catch (final NullPointerException ex) {
+			// This exception occurs, when the projectsBean has not been initialized
+			CurrentCockpitBean.LOG.error("An error occured while loading the project.", ex);
+			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectLoadingException());
+		}
 	}
 
 	/**
@@ -114,31 +150,140 @@ public class CurrentCockpitBean {
 
 		// Now add the entries from the current view
 		if (this.activeView != null) {
-			final FacesContext fc = FacesContext.getCurrentInstance();
-			final Application application = fc.getApplication();
-
-			// Add a panel for every display connector we have
-			final List<MIDisplayConnector> connectors = this.activeView.getDisplayConnectors();
-			long currId = 0;
-			for (final MIDisplayConnector connector : connectors) {
-				final Panel panel = (Panel) application.createComponent(fc, "org.primefaces.component.Panel", "org.primefaces.component.PanelRenderer");
-				panel.setId("displayConnectorPanel_" + currId);
-				panel.setHeader(connector.getName());
-				panel.setClosable(false);
-				panel.setToggleable(false);
-
-				this.getDashboard().getChildren().add(panel);
-				final DashboardColumn column = this.dashboard.getModel().getColumn(0);
-				column.addWidget(panel.getId());
-				final HtmlOutputText text = new HtmlOutputText();
-				text.setValue("N/A");
-
-				panel.getChildren().add(text);
-				currId++;
+
+			final List<List<MIDisplayConnector>> layout = this.cockpitLayout.getCurrentLayout(this.activeView);
+
+			for (int col = 0; col < NUMBER_COLUMNS; col++) {
+				final DashboardColumn column = this.dashboard.getModel().getColumn(col);
+
+				for (final MIDisplayConnector displayConnector : layout.get(col)) {
+					final Panel panel = this.createPanelFromDisplayConnector(displayConnector);
+
+					this.dashboard.getChildren().add(panel);
+					column.addWidget(panel.getId());
+				}
 			}
 		}
 	}
 
+	private Panel createPanelFromDisplayConnector(final MIDisplayConnector connector) {
+		final FacesContext fc = FacesContext.getCurrentInstance();
+
+		final Application application = fc.getApplication();
+		final Panel panel = (Panel) application.createComponent(fc, "org.primefaces.component.Panel", "org.primefaces.component.PanelRenderer");
+		final String id = this.displayConnectorToID(connector);
+
+		// Set the usual properties of the panel
+		panel.setId(id);
+		panel.setHeader(connector.getName());
+		panel.setClosable(true);
+		panel.setToggleable(false);
+
+		final HtmlOutputText text = new HtmlOutputText();
+		text.setValue("N/A");
+		panel.getChildren().add(text);
+
+		/*
+		 * final GraphicImage graphImg = (GraphicImage) application.createComponent(fc, "org.primefaces.component.GraphicImage",
+		 * "org.primefaces.component.GraphicImageRenderer");
+		 * try {
+		 * final BufferedImage bufferedImg = new BufferedImage(100, 25, BufferedImage.TYPE_INT_RGB);
+		 * final Graphics2D g2 = bufferedImg.createGraphics();
+		 * g2.drawString("This is a text", 0, 10);
+		 * final ByteArrayOutputStream os = new ByteArrayOutputStream();
+		 * ImageIO.write(bufferedImg, "png", os);
+		 * final StreamedContent graphicText = new DefaultStreamedContent(new ByteArrayInputStream(os.toByteArray()), "image/png");
+		 * 
+		 * graphImg.setValue(graphicText);
+		 * } catch (final Exception ex) {
+		 * ex.printStackTrace();
+		 * }
+		 * 
+		 * panel.getChildren().add(graphImg);
+		 */
+
+		return panel;
+	}
+
+	private String displayConnectorToID(final MIDisplayConnector displayConnector) {
+		return ID_PREFIX + this.displayConnectors.get(displayConnector);
+	}
+
+	/**
+	 * Checks whether the analysis is currently running.
+	 * 
+	 * @return true if and only if the analysis is running.
+	 */
+	public boolean isAnalysisRunning() {
+		try {
+			return this.projectService.getCurrentState(this.projectName) == AnalysisController.STATE.RUNNING;
+		} catch (final NullPointerException ex) {
+			// This exception can occur, when the projectsBean has not been initialized
+			LOG.warn("A null pointer exception occured.", ex);
+		}
+		return false;
+	}
+
+	/**
+	 * Checks whether the analysis is currently in the ready state.
+	 * 
+	 * @return true if and only if the analysis is ready to be started.
+	 */
+	public boolean isAnalysisReady() {
+		try {
+			return this.projectService.getCurrentState(this.projectName) == AnalysisController.STATE.READY;
+		} catch (final NullPointerException ex) {
+			// This exception can occur, when the projectsBean has not been initialized
+			LOG.warn("A null pointer exception occured.", ex);
+		}
+		return false;
+	}
+
+	/**
+	 * Checks whether the analysis is not available.
+	 * 
+	 * @return true if and only if the analysis is <b>not</b> available.
+	 */
+	public boolean isAnalysisNotAvailable() {
+		try {
+			return this.projectService.getCurrentState(this.projectName) == null;
+		} catch (final NullPointerException ex) {
+			// This exception can occur, when the projectsBean has not been initialized
+			LOG.warn("A null pointer exception occured.", ex);
+		}
+		return true;
+	}
+
+	/**
+	 * Checks whether the analysis is currently terminated.
+	 * 
+	 * @return true if and only if the analysis has been terminated.
+	 */
+	public boolean isAnalysisTerminated() {
+		try {
+			return this.projectService.getCurrentState(this.projectName) == AnalysisController.STATE.TERMINATED;
+		} catch (final NullPointerException ex) {
+			// This exception can occur, when the projectsBean has not been initialized
+			LOG.warn("A null pointer exception occured.", ex);
+		}
+		return false;
+	}
+
+	/**
+	 * Checks whether the analysis is currently in the failed state.
+	 * 
+	 * @return true if and only if the analysis has failed.
+	 */
+	public boolean isAnalysisFailed() {
+		try {
+			return this.projectService.getCurrentState(this.projectName) == AnalysisController.STATE.FAILED;
+		} catch (final NullPointerException ex) {
+			// This exception can occur, when the projectsBean has not been initialized
+			LOG.warn("A null pointer exception occured.", ex);
+		}
+		return false;
+	}
+
 	/**
 	 * Clears the dashboard and removes all children within it.
 	 */
@@ -161,33 +306,62 @@ public class CurrentCockpitBean {
 		this.projectName = newName;
 	}
 
+	public String getProjectName() {
+		return this.projectName;
+	}
+
+	public void updateDisplays() {
+		for (final UIComponent child : this.dashboard.getChildren()) {
+			final int id = Integer.valueOf(child.getId().replace(ID_PREFIX, ""));
+			final MIDisplayConnector conn = this.displayConnectors.get(id);
+			this.updatePlainTextDisplay(child, conn.getName());
+			this.updatePlotDisplay(child, conn.getName());
+		}
+	}
+
 	/**
-	 * This method initializes the bean by using the current project name to load the project. <b>Do not call this method manually. It will only be accessed by
-	 * Spring.</b>
+	 * @param child
+	 * @param name
 	 */
-	public void initalize() {
-		try {
-			// Make sure that the initialization will only be done for the init request.
-			if (!FacesContext.getCurrentInstance().isPostback()) {
-				// Remember the given parameters
-				this.project = this.projectsBean.openProject(this.projectName);
+	private void updatePlotDisplay(final UIComponent child, final String displayName) {
+		if ((this.activeView != null) && (this.projectName != null)) {
+			try {
+				final Object displayObj = this.projectService.getDisplay(this.projectName, this.activeView.getName(), displayName);
+				final Collection<Long> entries = (Collection<Long>) new Mirror().on(displayObj).invoke().method("getEntries").withoutArgs();
+
+				final FacesContext fc = FacesContext.getCurrentInstance();
+
+				final Application application = fc.getApplication();
+
+				child.getChildren().clear();
+
+				final LineChart lineChart = (LineChart) application.createComponent(fc, "org.primefaces.component.chart.LineChart",
+						"org.primefaces.component.chart.LineChartRenderer");
 
-				if (this.project != null) {
-					this.fillDashboard();
+				lineChart.setTitle("Title");
+				final CartesianChartModel linearModel = new CartesianChartModel();
+
+				final LineChartSeries series = new LineChartSeries();
+				series.setLabel("Series");
+
+				int i = 0;
+				for (final Long entry : entries) {
+					series.set(i, entry);
+					i++;
 				}
+
+				linearModel.addSeries(series);
+				lineChart.setValue(linearModel);
+				child.getChildren().add(lineChart);
+			} catch (final DisplayNotFoundException ex) {
+				CurrentCockpitBean.LOG.warn("Display not found.", ex);
+			} catch (final MirrorException ex) {
+				CurrentCockpitBean.LOG.warn("Reflection exception.", ex);
+			} catch (final InvalidAnalysisStateException ex) {
+				CurrentCockpitBean.LOG.info("Project is in invalid state.", ex);
 			}
-		} catch (final ProjectLoadException ex) {
-			CurrentCockpitBean.LOG.error("An error occured while loading the project.", ex);
-			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectLoadingException());
-		} catch (final NullPointerException ex) {
-			// This exception occurs, when the projectsBean has not been initialized
-			CurrentCockpitBean.LOG.error("An error occured while loading the project.", ex);
-			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectLoadingException());
 		}
-	}
 
-	public String getProjectName() {
-		return this.projectName;
 	}
 
 	/**
@@ -198,20 +372,27 @@ public class CurrentCockpitBean {
 	 * @return The current content of the display, if it exists. If the display does not exist or the active view is not set 'N/A' will be returned. If an access to
 	 *         the display fails, "Error" will be returned.
 	 */
-	public String updatePlainTextDisplay(final String displayName) {
+	public void updatePlainTextDisplay(final UIComponent child, final String displayName) {
 		if ((this.activeView != null) && (this.projectName != null)) {
 			try {
+				final FacesContext fc = FacesContext.getCurrentInstance();
+
+				fc.getApplication();
+				child.getChildren().clear();
 				final Object displayObj = this.projectService.getDisplay(this.projectName, this.activeView.getName(), displayName);
-				return (String) new Mirror().on(displayObj).invoke().method("getText").withoutArgs();
+				final String text = (String) new Mirror().on(displayObj).invoke().method("getText").withoutArgs();
+				final HtmlOutputText t = new HtmlOutputText();
+				t.setValue(text);
+				child.getChildren().add(t);
 			} catch (final DisplayNotFoundException ex) {
 				CurrentCockpitBean.LOG.warn("Display not found.", ex);
 			} catch (final MirrorException ex) {
 				CurrentCockpitBean.LOG.warn("Reflection exception.", ex);
 			} catch (final InvalidAnalysisStateException ex) {
-				CurrentCockpitBean.LOG.warn("Project is in invalid state.", ex);
+				CurrentCockpitBean.LOG.info("Project is in invalid state.", ex);
 			}
 		}
-		return "N/A";
+
 	}
 
 	/**
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java
index 5748e3c7d7023224abb09e202e2675ad89dd875c..e7d3098311f489e0c3c44518cfa4b5185fa960b4 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java
@@ -16,17 +16,12 @@
 
 package kieker.webgui.web.beans.view;
 
-import java.awt.Point;
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import javax.annotation.Nullable;
 import javax.faces.application.Application;
 import javax.faces.application.FacesMessage;
 import javax.faces.component.UIComponent;
@@ -36,9 +31,6 @@ import javax.faces.context.FacesContext;
 import javax.faces.event.AbortProcessingException;
 import javax.faces.event.AjaxBehaviorEvent;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-
 import kieker.analysis.model.analysisMetaModel.MIAnalysisMetaModelFactory;
 import kieker.analysis.model.analysisMetaModel.MIDisplay;
 import kieker.analysis.model.analysisMetaModel.MIDisplayConnector;
@@ -61,6 +53,7 @@ import kieker.webgui.service.IProjectService;
 import kieker.webgui.web.beans.application.GlobalPropertiesBean;
 import kieker.webgui.web.beans.application.ProjectsBean;
 import kieker.webgui.web.beans.session.UserBean;
+import kieker.webgui.web.utility.CockpitLayout;
 
 import org.primefaces.component.behavior.ajax.AjaxBehavior;
 import org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl;
@@ -74,8 +67,6 @@ import org.primefaces.model.DashboardModel;
 import org.primefaces.model.DefaultDashboardColumn;
 import org.primefaces.model.DefaultDashboardModel;
 
-import org.eclipse.emf.common.util.EList;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
@@ -91,9 +82,11 @@ import org.springframework.stereotype.Component;
 @Scope("view")
 public class CurrentCockpitEditorBean {
 
-	private static final int NUMBER_COLUMNS = 2;
 	private static final Log LOG = LogFactory.getLog(CurrentCockpitEditorBean.class);
 
+	private static final String ID_PREFIX = "displayConnector_";
+	private static final int NUMBER_COLUMNS = 2;
+
 	private final MIAnalysisMetaModelFactory factory = MAnalysisMetaModelFactory.eINSTANCE;
 	@Autowired
 	private IProjectService projectService;
@@ -114,16 +107,47 @@ public class CurrentCockpitEditorBean {
 	@Autowired
 	private UserBean userBean;
 
-	private final Registry<MIDisplayConnector> connectors = new Registry<MIDisplayConnector>();
 	private MIDisplayConnector selectedNode = null;
 
+	private final Registry<MIDisplayConnector> displayConnectors = new Registry<MIDisplayConnector>();
+	private CockpitLayout cockpitLayout;
+
 	/**
 	 * Creates a new instance of this class. <b>Do not call this constructor manually. It will only be accessed by Spring.</b>
 	 */
 	public CurrentCockpitEditorBean() {
 		this.availableComponents = new ComponentListContainer(Collections.<ReaderDecorator>emptyList(), Collections.<FilterDecorator>emptyList(),
 				Collections.<RepositoryDecorator>emptyList());
-		this.createDashboard();
+	}
+
+	/**
+	 * This method initializes the bean by using the current project name to load the project. <b>Do not call this method manually. It will only be accessed by
+	 * Spring.</b>
+	 */
+	public void initalize() {
+		try {
+			// Make sure that the initialization will only be done for the init request.
+			if (!FacesContext.getCurrentInstance().isPostback()) {
+				// Remember the given parameters
+				this.project = this.projectsBean.openProject(this.projectName);
+				if (this.project != null) {
+					// Remember the current time! This is important for the later comparison of the time stamps.
+					this.resetTimeStamp();
+					this.reloadComponents();
+
+					this.createDashboard();
+					this.cockpitLayout = new CockpitLayout(this.project, this.projectService.getCockpitLayout(this.projectName), NUMBER_COLUMNS);
+				}
+
+				this.unsavedModifications = false;
+			}
+		} catch (final ProjectLoadException ex) {
+			CurrentCockpitEditorBean.LOG.error("An error occured while loading the project.", ex);
+			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project.");
+		} catch (final NullPointerException ex) {
+			CurrentCockpitEditorBean.LOG.error("An error occured while loading the project.", ex);
+			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project.");
+		}
 	}
 
 	/**
@@ -142,13 +166,13 @@ public class CurrentCockpitEditorBean {
 		final FacesContext fc = FacesContext.getCurrentInstance();
 		final Application application = fc.getApplication();
 
-		// Create the primefaces dashboard
+		// Create the Primefaces dashboard
 		this.dashboard = (Dashboard) application.createComponent(fc, "org.primefaces.component.Dashboard", "org.primefaces.component.DashboardRenderer");
 		this.dashboard.setId("dashboard");
 
 		// Create the model and add the columns
 		this.dashboardModel = new DefaultDashboardModel();
-		for (int i = 0; i < CurrentCockpitEditorBean.NUMBER_COLUMNS; i++) {
+		for (int i = 0; i < NUMBER_COLUMNS; i++) {
 			final DashboardColumn column = new DefaultDashboardColumn();
 			this.dashboardModel.addColumn(column);
 		}
@@ -160,7 +184,7 @@ public class CurrentCockpitEditorBean {
 	}
 
 	/**
-	 * Fills the initial dashboard object.
+	 * Fills the dashboard using the currently active view.
 	 */
 	private void fillDashboard() {
 		// Dump the old entries
@@ -168,67 +192,19 @@ public class CurrentCockpitEditorBean {
 
 		// Now add the entries from the current view
 		if (this.activeView != null) {
-			// Add a panel for every display connector we have
-			this.currId = 0;
 
-			for (int col = 0; col < 2; col++) {
-				final Collection<MIDisplayConnector> displayConnectors = this.getSortedDisplayConnectors(this.activeView.getDisplayConnectors(), col);
+			final List<List<MIDisplayConnector>> layout = this.cockpitLayout.getCurrentLayout(this.activeView);
+
+			for (int col = 0; col < NUMBER_COLUMNS; col++) {
 				final DashboardColumn column = this.dashboard.getModel().getColumn(col);
 
-				for (final MIDisplayConnector connector : displayConnectors) {
-					final Panel panel = this.createPanelFromDisplayConnector(connector);
+				for (final MIDisplayConnector displayConnector : layout.get(col)) {
+					final Panel panel = this.createPanelFromDisplayConnector(displayConnector);
 
 					this.dashboard.getChildren().add(panel);
 					column.addWidget(panel.getId());
-
-					this.currId++;
-				}
-			}
-		}
-	}
-
-	private Collection<MIDisplayConnector> getSortedDisplayConnectors(final EList<MIDisplayConnector> eList, final int col) {
-		final List<MIDisplayConnector> l = new ArrayList<MIDisplayConnector>(Collections2.filter(eList, new ColumnPredicate(col)));
-
-		Collections.sort(l, new PosComparator());
-
-		return l;
-	}
-
-	/**
-	 * This method initializes the bean by using the current project name to load the project. <b>Do not call this method manually. It will only be accessed by
-	 * Spring.</b>
-	 */
-	public void initalize() {
-
-		try {
-			// Make sure that the initialization will only be done for the init request.
-			if (!FacesContext.getCurrentInstance().isPostback()) {
-				// Remember the given parameters
-				this.project = this.projectsBean.openProject(this.projectName);
-				if (this.project != null) {
-					// Remember the current time! This is important for the later comparison of the time stamps.
-					this.resetTimeStamp();
-					this.reloadComponents();
-
-					this.stringToLayout(this.projectService.getCockpitLayout(this.projectName));
-
-					// Update the class loader and the specific classes used within various methods in this bean
-					this.fillDashboard();
-
-					if (!this.project.getViews().isEmpty()) {
-						this.setActiveView(this.project.getViews().get(0));
-					}
 				}
-
-				this.unsavedModifications = false;
 			}
-		} catch (final ProjectLoadException ex) {
-			CurrentCockpitEditorBean.LOG.error("An error occured while loading the project.", ex);
-			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project.");
-		} catch (final NullPointerException ex) {
-			CurrentCockpitEditorBean.LOG.error("An error occured while loading the project.", ex);
-			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project.");
 		}
 	}
 
@@ -302,7 +278,7 @@ public class CurrentCockpitEditorBean {
 	public void saveProject(final boolean overwriteNewerProject) {
 		try {
 			this.projectService.saveProject(this.projectName, this.project, this.timeStamp, overwriteNewerProject, this.userBean.getUsername(), null,
-					this.layoutToString());
+					this.cockpitLayout.serializeToString());
 			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_INFO, this.globalPropertiesBean.getMsgProjectSaved());
 			// Update the time stamp!
 			this.resetTimeStamp();
@@ -359,7 +335,9 @@ public class CurrentCockpitEditorBean {
 			final MIView view = this.factory.createView();
 			view.setName(viewName);
 			view.setDescription("No description available.");
+
 			this.project.getViews().add(view);
+			this.cockpitLayout.addView(view);
 
 			this.setModificationsFlag();
 		}
@@ -390,6 +368,7 @@ public class CurrentCockpitEditorBean {
 	 */
 	public void deleteView(final MIView view) {
 		this.project.getViews().remove(view);
+		this.cockpitLayout.removeView(view);
 
 		this.setModificationsFlag();
 	}
@@ -429,12 +408,12 @@ public class CurrentCockpitEditorBean {
 	}
 
 	private void panelCloseEvent(final AjaxBehaviorEvent event) {
-		if (CurrentCockpitEditorBean.this.activeView != null) {
+		if (this.activeView != null) {
 			final String id = ((Panel) event.getSource()).getId();
-			final MIDisplayConnector connector = CurrentCockpitEditorBean.this.idToDisplayConnector(id);
+			final MIDisplayConnector connector = this.idToDisplayConnector(id);
 
-			CurrentCockpitEditorBean.this.activeView.getDisplayConnectors().remove(connector);
-			CurrentCockpitEditorBean.this.saveLayoutOfCurrentView();
+			this.activeView.getDisplayConnectors().remove(connector);
+			this.cockpitLayout.removeDisplayConnector(this.activeView, connector);
 		}
 	}
 
@@ -456,20 +435,26 @@ public class CurrentCockpitEditorBean {
 			this.getDashboard().getChildren().add(panel);
 			final DashboardColumn column = this.dashboardModel.getColumn(0);
 			column.addWidget(panel.getId());
-			this.currId++;
+
+			this.cockpitLayout.addDisplayConnector(this.activeView, connector, 0);
 
 			this.setModificationsFlag();
 
-			this.saveLayoutOfCurrentView();
 		}
 	}
 
-	private static final String ID_PREFIX = "displayConnector_";
-
-	final Map<MIView, Map<MIDisplayConnector, Point>> connectorPositions = new HashMap<MIView, Map<MIDisplayConnector, Point>>();
-
 	public void handleReorder(final DashboardReorderEvent event) {
-		this.saveLayoutOfCurrentView();
+		final MIDisplayConnector connector = this.idToDisplayConnector(event.getWidgetId());
+
+		// Primefaces uses null as sender column index, if the sender is the same as the receiver. We correct this.
+		final int senderIndex;
+		if (event.getSenderColumnIndex() != null) {
+			senderIndex = event.getSenderColumnIndex();
+		} else {
+			senderIndex = event.getColumnIndex();
+		}
+
+		this.cockpitLayout.moveDisplayConnector(this.activeView, connector, senderIndex, event.getColumnIndex(), event.getItemIndex());
 	}
 
 	/**
@@ -510,7 +495,7 @@ public class CurrentCockpitEditorBean {
 		final String fullID = paramMap.get("id");
 		final String shortID = fullID.substring(fullID.indexOf(':') + "displayConnector_".length() + 1);
 
-		final MIDisplayConnector connector = this.connectors.get(Integer.parseInt(shortID));
+		final MIDisplayConnector connector = this.displayConnectors.get(Integer.parseInt(shortID));
 		if (connector != null) {
 			this.selectedNode = connector;
 		}
@@ -572,98 +557,15 @@ public class CurrentCockpitEditorBean {
 		this.dashboard.getChildren().clear();
 	}
 
-	private void saveLayoutOfCurrentView() {
-		if (this.activeView != null) {
-			final Map<MIDisplayConnector, Point> layout = new HashMap<MIDisplayConnector, Point>();
-
-			// Run through all columns and put the position of every widget into the map
-			int col = 0;
-			for (final DashboardColumn column : this.dashboardModel.getColumns()) {
-				int row = 0;
-				for (final String widgetID : column.getWidgets()) {
-					layout.put(this.idToDisplayConnector(widgetID), new Point(col, row));
-					row++;
-				}
-				col++;
-			}
-
-			// Store the map for the whole view
-			this.connectorPositions.put(this.activeView, layout);
-		}
-	}
-
-	private void stringToLayout(final String layout) {
-		final String[] elements = layout.split(" ");
-		int i = 0;
-
-		for (final MIView view : this.project.getViews()) {
-			final Map<MIDisplayConnector, Point> positions = new HashMap<MIDisplayConnector, Point>();
-			this.connectorPositions.put(view, positions);
-			for (final MIDisplayConnector connector : view.getDisplayConnectors()) {
-				final Point pos = new Point(Integer.valueOf(elements[i]), Integer.valueOf(elements[i + 1]));
-
-				positions.put(connector, pos);
-
-				i += 2;
-			}
-		}
-
-	}
-
-	private String layoutToString() {
-		final StringBuilder builder = new StringBuilder();
-
-		for (final MIView view : this.project.getViews()) {
-			final Map<MIDisplayConnector, Point> positions = this.connectorPositions.get(view);
-			for (final MIDisplayConnector connector : view.getDisplayConnectors()) {
-				final Point pos = positions.get(connector);
-
-				builder.append(pos.x);
-				builder.append(' ');
-				builder.append(pos.y);
-				builder.append(' ');
-			}
-		}
-
-		return builder.toString();
-	}
-
 	private String displayConnectorToID(final MIDisplayConnector displayConnector) {
-		return ID_PREFIX + this.connectors.get(displayConnector);
+		return ID_PREFIX + this.displayConnectors.get(displayConnector);
 	}
 
 	private MIDisplayConnector idToDisplayConnector(final String id) {
 		final String shortID = id.substring(ID_PREFIX.length());
 		final int intID = Integer.valueOf(shortID);
 
-		return this.connectors.get(intID);
-	}
-
-	private class PosComparator implements Comparator<MIDisplayConnector> {
-
-		@Override
-		public int compare(final MIDisplayConnector o1, final MIDisplayConnector o2) {
-			final int pos1 = CurrentCockpitEditorBean.this.connectorPositions.get(CurrentCockpitEditorBean.this.activeView).get(o1).y;
-			final int pos2 = CurrentCockpitEditorBean.this.connectorPositions.get(CurrentCockpitEditorBean.this.activeView).get(o2).y;
-
-			return pos1 - pos2;
-		}
-
-	}
-
-	private class ColumnPredicate implements Predicate<MIDisplayConnector> {
-
-		private final int col;
-
-		public ColumnPredicate(final int col) {
-			this.col = col;
-		}
-
-		@Override
-		public boolean apply(@Nullable final MIDisplayConnector key) {
-			return CurrentCockpitEditorBean.this.connectorPositions.get(CurrentCockpitEditorBean.this.activeView).get(key).x == this.col;
-		}
-
+		return this.displayConnectors.get(intID);
 	}
 
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/web/utility/CockpitLayout.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/utility/CockpitLayout.java
new file mode 100644
index 0000000000000000000000000000000000000000..283fa93305281d1cc5f1236e6c85262fadc783d1
--- /dev/null
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/utility/CockpitLayout.java
@@ -0,0 +1,311 @@
+/***************************************************************************
+ * Copyright 2013 Kieker Project (http://kieker-monitoring.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ***************************************************************************/
+
+package kieker.webgui.web.utility;
+
+import java.awt.Point;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+
+import kieker.analysis.model.analysisMetaModel.MIDisplayConnector;
+import kieker.analysis.model.analysisMetaModel.MIProject;
+import kieker.analysis.model.analysisMetaModel.MIView;
+
+/**
+ * This is a helper class to manage and modify the layout of the cockpit.
+ * 
+ * @author Nils Christian Ehmke
+ */
+public class CockpitLayout {
+
+	private final Map<MIView, List<List<MIDisplayConnector>>> layout = new HashMap<MIView, List<List<MIDisplayConnector>>>();
+	private final int numberColumns;
+	private final MIProject project;
+
+	/**
+	 * Creates a new instance of this class using the given parameters.
+	 * 
+	 * @param project
+	 *            The corresponding project to the layout.
+	 * @param layoutString
+	 *            The initial layout string. This parameter is optional and can be null.
+	 * @param numberColumns
+	 *            The number of columns for the layout.
+	 */
+	public CockpitLayout(final MIProject project, final String layoutString, final int numberColumns) {
+		this.numberColumns = numberColumns;
+		this.project = project;
+
+		if (layoutString != null) {
+			this.addProjectViewsAndDisplayConnectors(layoutString);
+		} else {
+			this.addProjectViewsAndDisplayConnectors();
+		}
+	}
+
+	/**
+	 * Delivers the current layout of the given view. The result is a list of lists. Each of the lists represent a column. Each column contains the display
+	 * connectors in the correct order.
+	 * 
+	 * @param view
+	 *            The view whose layout will be delivered.
+	 * 
+	 * @return A copy of the current layout.
+	 */
+	public List<List<MIDisplayConnector>> getCurrentLayout(final MIView view) {
+		final List<List<MIDisplayConnector>> original = this.layout.get(view);
+		final List<List<MIDisplayConnector>> copy = new ArrayList<List<MIDisplayConnector>>();
+
+		for (final List<MIDisplayConnector> columnOriginal : original) {
+			final List<MIDisplayConnector> columnCopy = new ArrayList<MIDisplayConnector>();
+			columnCopy.addAll(columnOriginal);
+
+			copy.add(columnCopy);
+		}
+
+		return copy;
+	}
+
+	/**
+	 * Adds a view to manage.
+	 * 
+	 * @param view
+	 *            The new view.
+	 */
+	public final void addView(final MIView view) {
+		final List<List<MIDisplayConnector>> columns = new ArrayList<List<MIDisplayConnector>>();
+		this.layout.put(view, columns);
+
+		for (int i = 0; i < this.numberColumns; i++) {
+			columns.add(new ArrayList<MIDisplayConnector>());
+		}
+	}
+
+	/**
+	 * Removes a view and its layout from this object.
+	 * 
+	 * @param view
+	 *            The view to remove.
+	 */
+	public final void removeView(final MIView view) {
+		this.layout.remove(view);
+	}
+
+	/**
+	 * Adds a display connector to the layout. It will be added at the end of the given column.
+	 * 
+	 * @param view
+	 *            The corresponding view.
+	 * @param displayConnector
+	 *            The display connector to add.
+	 * @param column
+	 *            The column index. It is assumed that this is a valid index.
+	 */
+	public final void addDisplayConnector(final MIView view, final MIDisplayConnector displayConnector, final int column) {
+		this.layout.get(view).get(column).add(displayConnector);
+	}
+
+	/**
+	 * Moves a display connector from one column to another.
+	 * 
+	 * @param view
+	 *            The corresponding view.
+	 * @param displayConnector
+	 *            The display connector to move.
+	 * @param fromColumn
+	 *            The source column.
+	 * @param column
+	 *            The new column.
+	 * @param row
+	 *            The new row of the connector.
+	 */
+	public final void moveDisplayConnector(final MIView view, final MIDisplayConnector displayConnector, final int fromColumn, final int column, final int row) {
+		this.layout.get(view).get(fromColumn).remove(displayConnector);
+		this.layout.get(view).get(column).add(row, displayConnector);
+	}
+
+	/**
+	 * Removes a display connector and its layout from this object.
+	 * 
+	 * @param view
+	 *            The corresponding view.
+	 * @param displayConnector
+	 *            The display connector to remove.
+	 */
+	public final void removeDisplayConnector(final MIView view, final MIDisplayConnector displayConnector) {
+		// Find the correct column and remove the connector
+		for (final List<MIDisplayConnector> column : this.layout.get(view)) {
+			if (column.contains(displayConnector)) {
+				column.remove(displayConnector);
+				break;
+			}
+		}
+	}
+
+	/**
+	 * Serializes the current layout into a string. The string can be used in the constructor of this class to load a layout.
+	 * 
+	 * @return A string representation of this layout.
+	 */
+	public String serializeToString() {
+		final Map<MIDisplayConnector, Point> positions = this.extractPositionOfEveryDisplayConnector();
+		final StringBuilder builder = new StringBuilder();
+
+		for (final MIView view : this.project.getViews()) {
+			for (final MIDisplayConnector displayConnector : view.getDisplayConnectors()) {
+				final Point position = positions.get(displayConnector);
+				builder.append(position.x).append(' ').append(position.y).append(' ');
+			}
+		}
+
+		return builder.toString();
+	}
+
+	private Map<MIDisplayConnector, Point> extractPositionOfEveryDisplayConnector() {
+		final Map<MIDisplayConnector, Point> result = new HashMap<MIDisplayConnector, Point>();
+
+		for (final MIView view : this.project.getViews()) {
+			int col = 0;
+			for (final List<MIDisplayConnector> column : this.layout.get(view)) {
+				int row = 0;
+				for (final MIDisplayConnector displayConnector : column) {
+					result.put(displayConnector, new Point(col, row));
+					row++;
+				}
+				col++;
+			}
+		}
+
+		return result;
+	}
+
+	private void addProjectViewsAndDisplayConnectors() {
+		for (final MIView view : this.project.getViews()) {
+			this.addView(view);
+			for (final MIDisplayConnector displayConnector : view.getDisplayConnectors()) {
+				this.addDisplayConnector(view, displayConnector, 0);
+			}
+		}
+	}
+
+	private void addProjectViewsAndDisplayConnectors(final String layoutString) {
+		final String[] layoutElements = layoutString.split(" ");
+
+		final Map<MIView, Map<MIDisplayConnector, Point>> positions = new HashMap<MIView, Map<MIDisplayConnector, Point>>();
+		// Extract the position of every connector
+		int pos = 0;
+		for (final MIView view : this.project.getViews()) {
+			final Map<MIDisplayConnector, Point> positionSubMap = new HashMap<MIDisplayConnector, Point>();
+			positions.put(view, positionSubMap);
+
+			for (final MIDisplayConnector displayConnector : view.getDisplayConnectors()) {
+				final int col = Integer.valueOf(layoutElements[pos]);
+				final int row = Integer.valueOf(layoutElements[pos + 1]);
+				positionSubMap.put(displayConnector, new Point(col, row));
+
+				pos += 2;
+			}
+		}
+
+		// We have to sort the display connectors so we can add them in the correct order
+		for (final MIView view : this.project.getViews()) {
+			this.addView(view);
+			for (int col = 0; col < this.numberColumns; col++) {
+				final List<MIDisplayConnector> displayConnectors = this.getSortedDisplayConnectorsFromColumn(positions.get(view), col);
+				for (final MIDisplayConnector displayConnector : displayConnectors) {
+					this.addDisplayConnector(view, displayConnector, col);
+				}
+			}
+		}
+	}
+
+	private List<MIDisplayConnector> getSortedDisplayConnectorsFromColumn(final Map<MIDisplayConnector, Point> positions, final int column) {
+		final List<MIDisplayConnector> result = new ArrayList<MIDisplayConnector>(Collections2.filter(positions.keySet(), new ColumnFilter(positions, column)));
+
+		Collections.sort(result, new RowComparator(positions));
+
+		return result;
+	}
+
+	/**
+	 * A comparator to sort the entries of a column using the row indexes.
+	 * 
+	 * @author Nils Christian Ehmke
+	 */
+	private static class RowComparator implements Comparator<MIDisplayConnector> {
+
+		private final Map<MIDisplayConnector, Point> positions;
+
+		/**
+		 * Creates a new instance of this class using the given parameters.
+		 * 
+		 * @param positions
+		 *            The map containing the positions of every connector.
+		 */
+		public RowComparator(final Map<MIDisplayConnector, Point> positions) {
+			this.positions = positions;
+		}
+
+		@Override
+		public int compare(final MIDisplayConnector o1, final MIDisplayConnector o2) {
+			final int row1 = this.positions.get(o1).y;
+			final int row2 = this.positions.get(o2).y;
+
+			return row1 - row2;
+		}
+
+	}
+
+	/**
+	 * A filter to get only the entries within a specific column.
+	 * 
+	 * @author Nils Christian Ehmke
+	 */
+	private static class ColumnFilter implements Predicate<MIDisplayConnector> {
+
+		private final Map<MIDisplayConnector, Point> positions;
+		private final int column;
+
+		/**
+		 * Creates a new instance of this class using the given parameters.
+		 * 
+		 * @param positions
+		 *            The map containing the positions of every connector.
+		 * @param column
+		 *            The column to filter.
+		 */
+		public ColumnFilter(final Map<MIDisplayConnector, Point> positions, final int column) {
+			this.positions = positions;
+			this.column = column;
+		}
+
+		@Override
+		public boolean apply(@Nullable final MIDisplayConnector displayConnector) {
+			return this.positions.get(displayConnector).x == this.column;
+		}
+
+	}
+
+}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/web/utility/package-info.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/utility/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..9f4b30e95bba6476de8112ea972b227c506690d5
--- /dev/null
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/utility/package-info.java
@@ -0,0 +1,22 @@
+/***************************************************************************
+ * Copyright 2013 Kieker Project (http://kieker-monitoring.net)
+ *
+ * Licensed 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.
+ ***************************************************************************/
+
+/**
+ * This package contains utility classes for the web layer of the application.
+ * 
+ * @author Nils Christian Ehmke
+ */
+package kieker.webgui.web.utility;
\ No newline at end of file
diff --git a/Kieker.WebGUI/src/main/resources/lang/Common_de.properties b/Kieker.WebGUI/src/main/resources/lang/Common_de.properties
index 183b2ae52e29712d6940d40eba58e5ca60b23612..e1738aca166b7cc0dbe6eff8eb640e5cb0f566a0 100644
--- a/Kieker.WebGUI/src/main/resources/lang/Common_de.properties
+++ b/Kieker.WebGUI/src/main/resources/lang/Common_de.properties
@@ -37,6 +37,18 @@ property = Eigenschaft
 value = Wert
 noPropertiesAvailable = Keine Eigenschaften vorhanden
 
+analysisControllerMsgNotInstantiated = Zeigt an, dass der AnalysisController noch nicht instanziiert wurde.
+analysisControllerMsgReady = Zeigt an, dass der AnalysisController zwar instanziiert, jedoch noch nicht gestartet wurde.
+analysisControllerMsgRunning = Zeigt an, dass der AnalysisController gestartet wurde und zur Zeit läuft.
+analysisControllerMsgFailed = Zeigt an, dass der AnalysisController terminiert oder abgestürzt ist.
+
+state = Status
+stateNA = N/A
+stateReady = Bereit
+stateRunning = Läuft
+stateTerminated = Beendet
+stateFailed = Absturz
+
 #------------------------------------------------------------------------------
 #
 # These are the messages for the settings dialog.
diff --git a/Kieker.WebGUI/src/main/resources/lang/Common_en.properties b/Kieker.WebGUI/src/main/resources/lang/Common_en.properties
index 7d49dd7b4bca7b19127081fa4c9f5cf959871cad..badbab4a2aab662c7152958b9118d477962e8d38 100644
--- a/Kieker.WebGUI/src/main/resources/lang/Common_en.properties
+++ b/Kieker.WebGUI/src/main/resources/lang/Common_en.properties
@@ -37,6 +37,18 @@ property = Property
 value = Value
 noPropertiesAvailable = No properties available
 
+analysisControllerMsgNotInstantiated = Indicates that the AnalysisController has not been instantiated yet.
+analysisControllerMsgReady = Indicates that the AnalysisController has been instantiated, but not yet started.
+analysisControllerMsgRunning = Indicates that the AnalysisController has been started and is running.
+analysisControllerMsgFailed = Indicates that the AnalysisController has been terminated or has failed.
+
+state = State
+stateNA = N/A
+stateReady = Ready
+stateRunning = Running
+stateTerminated = Terminated
+stateFailed = Failed
+
 #------------------------------------------------------------------------------
 #
 # These are the messages for the settings dialog.
diff --git a/Kieker.WebGUI/src/main/resources/lang/ControllerPage_de.properties b/Kieker.WebGUI/src/main/resources/lang/ControllerPage_de.properties
index 668c39b739568afeeb60871304c2cf1ed94e281a..7b4f450d445708289cf363f4b1e0f6595e9c97fa 100644
--- a/Kieker.WebGUI/src/main/resources/lang/ControllerPage_de.properties
+++ b/Kieker.WebGUI/src/main/resources/lang/ControllerPage_de.properties
@@ -10,19 +10,8 @@ analysisControllerCleaAnalysisController = Analyse Zur
 analysisControllerStartAnalysis = Analyse Starten
 analysisControllerStopAnalysis = Analyse Stoppen
 
-analysisControllerMsgNotInstantiated = Zeigt an, dass der AnalysisController noch nicht instanziiert wurde.
-analysisControllerMsgReady = Zeigt an, dass der AnalysisController zwar instanziiert, jedoch noch nicht gestartet wurde.
-analysisControllerMsgRunning = Zeigt an, dass der AnalysisController gestartet wurde und zur Zeit läuft.
-analysisControllerMsgFailed = Zeigt an, dass der AnalysisController terminiert oder abgestürzt ist.
-
 control = Steuerung
 
 analysisControllerLog = AnalysisController Log
 personalLog = Persönlicher Log
 
-state = Status
-stateNA = N/A
-stateReady = Bereit
-stateRunning = Läuft
-stateTerminated = Beendet
-stateFailed = Absturz
\ No newline at end of file
diff --git a/Kieker.WebGUI/src/main/resources/lang/ControllerPage_en.properties b/Kieker.WebGUI/src/main/resources/lang/ControllerPage_en.properties
index db0e50a153c5cd4287e1102aca510984863512d6..9d8b17b801cb4d3828ca7aa2db306750bcb04b2d 100644
--- a/Kieker.WebGUI/src/main/resources/lang/ControllerPage_en.properties
+++ b/Kieker.WebGUI/src/main/resources/lang/ControllerPage_en.properties
@@ -10,19 +10,8 @@ analysisControllerCleaAnalysisController = Reset Analysis
 analysisControllerStartAnalysis = Start Analysis
 analysisControllerStopAnalysis = Stop Analysis
 
-analysisControllerMsgNotInstantiated = Indicates that the AnalysisController has not been instantiated yet.
-analysisControllerMsgReady = Indicates that the AnalysisController has been instantiated, but not yet started.
-analysisControllerMsgRunning = Indicates that the AnalysisController has been started and is running.
-analysisControllerMsgFailed = Indicates that the AnalysisController has been terminated or has failed.
-
 control = Control
 
 analysisControllerLog = AnalysisController Log
 personalLog = Personal Log
 
-state = State
-stateNA = N/A
-stateReady = Ready
-stateRunning = Running
-stateTerminated = Terminated
-stateFailed = Failed
\ No newline at end of file
diff --git a/Kieker.WebGUI/src/main/webapp/pages/CockpitEditorPage.xhtml b/Kieker.WebGUI/src/main/webapp/pages/CockpitEditorPage.xhtml
index cddfd5c77af83ac98eaaf71e47da179842d84162..8723907d66c90696514b8f2a7c6a1f5d6f24d45e 100644
--- a/Kieker.WebGUI/src/main/webapp/pages/CockpitEditorPage.xhtml
+++ b/Kieker.WebGUI/src/main/webapp/pages/CockpitEditorPage.xhtml
@@ -81,31 +81,32 @@
             </ui:define>
 
             <ui:define name="furtherLayoutUnits">
-                <p:layoutUnit position="west" resizable="true" maxSize="350" collapsible="true">
+                <p:layoutUnit position="west" size="300" header="Views" resizable="true" collapsible="true">
                     <h:form id="availableViewsForm">
-                        <p:dataTable value="#{currentCockpitEditorBean.project.views}" var="viewElem">
-                            <p:column headerText="View">
-                                <div align="center">
-                                    <p:commandLink id="dynaButton" style="font-weight: #{currentCockpitEditorBean.activeView == viewElem ? 'bold' : 'normal'}" value="#{viewElem.name}"/>
-
-                                    <p:menu overlay="true" trigger="dynaButton" my="left top" at="left bottom" style="width:210px">        
-                                        <p:menuitem icon="ui-icon-analysisEditor" value="  #{localizedCockpitEditorPageMessages.selectView}" action="#{currentCockpitEditorBean.setActiveView(viewElem)}" styleClass="element-with-whitespace" update=":messages :centerForm :availableViewsForm"/>
-                                        <p:separator/>
-                                        <p:menuitem  icon="ui-icon-copy"  styleClass="element-with-whitespace" value="  #{localizedCockpitEditorPageMessages.copyView}" />
-                                        <p:menuitem  icon="ui-icon-edit"  styleClass="element-with-whitespace" value="  #{localizedCockpitEditorPageMessages.renameView}"/>
-                                        <p:menuitem  icon="ui-icon-delete"  styleClass="element-with-whitespace" value="  #{localizedCockpitEditorPageMessages.deleteView}" action="#{currentCockpitEditorBean.deleteView(viewElem)}"/> 
-                                    </p:menu>
-                                </div>
-                            </p:column>
-                            <p:column headerText="# Elements"><div align="center">#{viewElem.displayConnectors.size()}</div></p:column>
-                            <p:column headerText="Description" width="50">
-                                <div align="center">
-                                    <p:inplace id="normalEditor" editor="true" >  
-                                        <p:inputText value="#{viewElem.description}" />
-                                    </p:inplace>  
-                                </div>
-                            </p:column>  
-                        </p:dataTable>
+                        <p:dataList value="#{currentCockpitEditorBean.project.views}" var="viewElem">  
+                            <p:commandLink id="viewLink" style="font-weight: #{currentCockpitEditorBean.activeView == viewElem ? 'bold' : 'normal'}" value="#{viewElem.name}"/>
+
+                            <p:tooltip for="viewLink">
+                                <b><h:outputText value="#{viewElem.name}"/></b>
+                                <br/>
+                                <h:outputText value="#{viewElem.description}" rendered="#{not empty viewElem.description}"/>
+                                <h:outputText value="No description available." rendered="#{empty viewElem.description}"/>
+                                <br/><br/>
+                                <b><h:outputText value="Displays"/></b>
+                                <p:dataList value="#{viewElem.displayConnectors}" var="connector">
+                                    #{connector.getName()}
+                                </p:dataList>
+                            </p:tooltip>
+
+                            <p:menu overlay="true" trigger="viewLink" my="left top" at="left bottom" style="width:210px">        
+                                <p:menuitem icon="ui-icon-analysisEditor" value="  #{localizedCockpitEditorPageMessages.selectView}" action="#{currentCockpitEditorBean.setActiveView(viewElem)}" styleClass="element-with-whitespace" update=":messages :centerForm :availableViewsForm"/>
+                                <p:separator/>
+                                <p:menuitem  icon="ui-icon-copy"  styleClass="element-with-whitespace" value="  #{localizedCockpitEditorPageMessages.copyView}" />
+                                <p:menuitem  icon="ui-icon-edit"  styleClass="element-with-whitespace" value="  #{localizedCockpitEditorPageMessages.renameView}"/>
+                                <p:menuitem  icon="ui-icon-edit"  styleClass="element-with-whitespace" value="  Edit Description"/>
+                                <p:menuitem  icon="ui-icon-delete"  styleClass="element-with-whitespace" value="  #{localizedCockpitEditorPageMessages.deleteView}" action="#{currentCockpitEditorBean.deleteView(viewElem)}"/> 
+                            </p:menu>
+                        </p:dataList>
                     </h:form>
                 </p:layoutUnit>
 
diff --git a/Kieker.WebGUI/src/main/webapp/pages/CockpitPage.xhtml b/Kieker.WebGUI/src/main/webapp/pages/CockpitPage.xhtml
index 93e8108b89a03be7956ac2b3577f10512b7ed0f1..77a05ba6e33b383df0567e29290c17190840e371 100644
--- a/Kieker.WebGUI/src/main/webapp/pages/CockpitPage.xhtml
+++ b/Kieker.WebGUI/src/main/webapp/pages/CockpitPage.xhtml
@@ -30,8 +30,8 @@
             <ui:define name="cssIncludes">
                 <link rel="stylesheet" type="text/css" href="#{root}/css/CockpitPage.css" />
             </ui:define>
-            
-               <ui:define name="js">
+
+            <ui:define name="js">
                 <!-- This javascript code will be executed in the onload-part of the body and shows a localized message via the growl-component. -->
                 <script>        
                     bodyLoaded = function() {
@@ -60,7 +60,7 @@
             <ui:define name="furtherLayoutUnits">
                 <p:layoutUnit position="west" size="300" header="Views" resizable="true" collapsible="true">
                     <h:form id="viewForm">
-                        <p:poll interval="1" update=":centerForm"/>
+                        <p:poll interval="1" listener="#{currentCockpitBean.updateDisplays()}" update=":centerForm"/>
                         <p:dataList value="#{currentCockpitBean.project.views}" var="currView">  
                             <p:commandLink style="#{currView == currentCockpitBean.activeView ? 'font-weight:bold' : ''}" value="#{currView.name}" action="#{currentCockpitBean.setActiveView(currView)}" id="viewLink" update=":viewForm"/>
                             <p:tooltip for="viewLink">
@@ -77,6 +77,29 @@
                         </p:dataList>
                     </h:form>
                 </p:layoutUnit>
+
+                <p:layoutUnit position="east" size="200" header="#{localizedMessages.state}" resizable="true" collapsible="true">
+                    <div align="center">
+                        <h:form id="ledsForm">
+                            <h:panelGrid columns="2" cellpadding="15">
+                                <h:graphicImage url="#{currentCockpitBean.isAnalysisNotAvailable() ? '../img/LEDs/Icon_LED_Red.png' : '../img/LEDs/Icon_LED_Gray.png'}" height="50px"/>
+                                <h:outputText value="#{localizedMessages.stateNA}"/>
+
+                                <h:graphicImage url="#{currentCockpitBean.isAnalysisReady() ? '../img/LEDs/Icon_LED_Yellow.png' : '../img/LEDs/Icon_LED_Gray.png'}" height="50px"/>
+                                <h:outputText value="#{localizedMessages.stateReady}"/>
+
+                                <h:graphicImage url="#{currentCockpitBean.isAnalysisRunning() ? '../img/LEDs/Icon_LED_Green.png' : '../img/LEDs/Icon_LED_Gray.png'}" height="50px"/>
+                                <h:outputText value="#{localizedMessages.stateRunning}"/>
+
+                                <h:graphicImage url="#{currentCockpitBean.isAnalysisTerminated() ? '../img/LEDs/Icon_LED_Red.png' : '../img/LEDs/Icon_LED_Gray.png'}" height="50px"/>
+                                <h:outputText value="#{localizedMessages.stateTerminated}"/>
+
+                                <h:graphicImage url="#{currentCockpitBean.isAnalysisFailed() ? '../img/LEDs/Icon_LED_Red.png' : '../img/LEDs/Icon_LED_Gray.png'}" height="50px"/>
+                                <h:outputText value="#{localizedMessages.stateFailed}"/>
+                            </h:panelGrid>
+                        </h:form>
+                    </div>
+                </p:layoutUnit>
             </ui:define>
 
         </ui:composition>
diff --git a/Kieker.WebGUI/src/main/webapp/pages/ControllerPage.xhtml b/Kieker.WebGUI/src/main/webapp/pages/ControllerPage.xhtml
index fa265db4d8b3f954a8d55db5fa507a9853252c3a..f1ec74599d4e120a1495f740b758a784393eb098 100644
--- a/Kieker.WebGUI/src/main/webapp/pages/ControllerPage.xhtml
+++ b/Kieker.WebGUI/src/main/webapp/pages/ControllerPage.xhtml
@@ -80,24 +80,24 @@
                     </h:form>  
                 </p:layoutUnit>
 
-                <p:layoutUnit position="east" size="200" header="#{localizedControllerPageMessages.state}" resizable="true" collapsible="true">
+                <p:layoutUnit position="east" size="200" header="#{localizedMessages.state}" resizable="true" collapsible="true">
                     <div align="center">
                         <h:form id="ledsForm">
                             <h:panelGrid columns="2" cellpadding="15">
                                 <h:graphicImage url="#{currentControllerBean.isAnalysisNotAvailable() ? '../img/LEDs/Icon_LED_Red.png' : '../img/LEDs/Icon_LED_Gray.png'}" height="50px"/>
-                                <h:outputText value="#{localizedControllerPageMessages.stateNA}"/>
+                                <h:outputText value="#{localizedMessages.stateNA}"/>
 
                                 <h:graphicImage url="#{currentControllerBean.isAnalysisReady() ? '../img/LEDs/Icon_LED_Yellow.png' : '../img/LEDs/Icon_LED_Gray.png'}" height="50px"/>
-                                <h:outputText value="#{localizedControllerPageMessages.stateReady}"/>
+                                <h:outputText value="#{localizedMessages.stateReady}"/>
 
                                 <h:graphicImage url="#{currentControllerBean.isAnalysisRunning() ? '../img/LEDs/Icon_LED_Green.png' : '../img/LEDs/Icon_LED_Gray.png'}" height="50px"/>
-                                <h:outputText value="#{localizedControllerPageMessages.stateRunning}"/>
+                                <h:outputText value="#{localizedMessages.stateRunning}"/>
 
                                 <h:graphicImage url="#{currentControllerBean.isAnalysisTerminated() ? '../img/LEDs/Icon_LED_Red.png' : '../img/LEDs/Icon_LED_Gray.png'}" height="50px"/>
-                                <h:outputText value="#{localizedControllerPageMessages.stateTerminated}"/>
+                                <h:outputText value="#{localizedMessages.stateTerminated}"/>
 
                                 <h:graphicImage url="#{currentControllerBean.isAnalysisFailed() ? '../img/LEDs/Icon_LED_Red.png' : '../img/LEDs/Icon_LED_Gray.png'}" height="50px"/>
-                                <h:outputText value="#{localizedControllerPageMessages.stateFailed}"/>
+                                <h:outputText value="#{localizedMessages.stateFailed}"/>
                             </h:panelGrid>
                         </h:form>
                     </div>
diff --git a/Kieker.WebGUI/src/test/java/kieker/webgui/web/utility/CockpitLayoutTest.java b/Kieker.WebGUI/src/test/java/kieker/webgui/web/utility/CockpitLayoutTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..fec1607d8db8d6de30d6ec2798d5204a0ab95de6
--- /dev/null
+++ b/Kieker.WebGUI/src/test/java/kieker/webgui/web/utility/CockpitLayoutTest.java
@@ -0,0 +1,372 @@
+/***************************************************************************
+ * Copyright 2013 Kieker Project (http://kieker-monitoring.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ***************************************************************************/
+
+package kieker.webgui.web.utility;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import kieker.analysis.model.analysisMetaModel.MIAnalysisMetaModelFactory;
+import kieker.analysis.model.analysisMetaModel.MIDisplayConnector;
+import kieker.analysis.model.analysisMetaModel.MIProject;
+import kieker.analysis.model.analysisMetaModel.MIView;
+
+/**
+ * A test for {@link CockpitLayout}.
+ * 
+ * @author Nils Christian Ehmke
+ */
+public class CockpitLayoutTest {
+
+	/**
+	 * Default constructor. <b>Do not use this constructor. This is just a test class and not to be used outside a JUnit test!</b>
+	 */
+	public CockpitLayoutTest() {
+		// No code necessary
+	}
+
+	/**
+	 * This test makes sure that the class stores and delivers the layout correctly.
+	 */
+	@Test
+	public void testLayoutPreservation() {
+		// Create the necessary components
+		final MIAnalysisMetaModelFactory factory = MIAnalysisMetaModelFactory.eINSTANCE;
+		final MIProject project = factory.createProject();
+
+		final CockpitLayout cockpitLayout = new CockpitLayout(project, null, 2);
+
+		final MIView view1 = factory.createView();
+		final MIView view2 = factory.createView();
+		final MIDisplayConnector displayConnector1 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector2 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector3 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector4 = factory.createDisplayConnector();
+
+		// Add everything to the cockpit layout
+		cockpitLayout.addView(view1);
+		cockpitLayout.addView(view2);
+
+		cockpitLayout.addDisplayConnector(view1, displayConnector1, 0);
+		cockpitLayout.addDisplayConnector(view1, displayConnector2, 0);
+		cockpitLayout.addDisplayConnector(view1, displayConnector3, 1);
+
+		cockpitLayout.addDisplayConnector(view2, displayConnector4, 0);
+
+		// Now get and check the layout
+		final List<List<MIDisplayConnector>> layout1 = cockpitLayout.getCurrentLayout(view1);
+		final List<List<MIDisplayConnector>> layout2 = cockpitLayout.getCurrentLayout(view2);
+
+		Assert.assertEquals("Invalid layout", 2, layout1.size());
+		Assert.assertEquals("Invalid layout", 2, layout2.size());
+
+		Assert.assertEquals("Invalid layout", 2, layout1.get(0).size());
+		Assert.assertEquals("Invalid layout", 1, layout1.get(1).size());
+
+		Assert.assertEquals("Invalid layout", 1, layout2.get(0).size());
+		Assert.assertEquals("Invalid layout", 0, layout2.get(1).size());
+
+		Assert.assertEquals("Invalid layout", displayConnector1, layout1.get(0).get(0));
+		Assert.assertEquals("Invalid layout", displayConnector2, layout1.get(0).get(1));
+		Assert.assertEquals("Invalid layout", displayConnector3, layout1.get(1).get(0));
+		Assert.assertEquals("Invalid layout", displayConnector4, layout2.get(0).get(0));
+	}
+
+	/**
+	 * This test makes sure that display connectors can be moved within the layout.
+	 */
+	@Test
+	public void testMovement() {
+		// Create the necessary components
+		final MIAnalysisMetaModelFactory factory = MIAnalysisMetaModelFactory.eINSTANCE;
+		final MIProject project = factory.createProject();
+
+		final CockpitLayout cockpitLayout = new CockpitLayout(project, null, 2);
+
+		final MIView view = factory.createView();
+
+		final MIDisplayConnector displayConnector1 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector2 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector3 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector4 = factory.createDisplayConnector();
+
+		// Add everything to the cockpit layout
+		cockpitLayout.addView(view);
+
+		cockpitLayout.addDisplayConnector(view, displayConnector1, 0);
+		cockpitLayout.addDisplayConnector(view, displayConnector2, 0);
+		cockpitLayout.addDisplayConnector(view, displayConnector3, 1);
+		cockpitLayout.addDisplayConnector(view, displayConnector4, 1);
+
+		// Now move a display connector
+		cockpitLayout.moveDisplayConnector(view, displayConnector3, 1, 0, 1);
+
+		// Now get and check the layout
+		final List<List<MIDisplayConnector>> layout = cockpitLayout.getCurrentLayout(view);
+
+		Assert.assertEquals("Invalid layout", 2, layout.size());
+
+		Assert.assertEquals("Invalid layout", 3, layout.get(0).size());
+		Assert.assertEquals("Invalid layout", 1, layout.get(1).size());
+
+		Assert.assertEquals("Invalid layout", displayConnector1, layout.get(0).get(0));
+		Assert.assertEquals("Invalid layout", displayConnector2, layout.get(0).get(2));
+		Assert.assertEquals("Invalid layout", displayConnector3, layout.get(0).get(1));
+		Assert.assertEquals("Invalid layout", displayConnector4, layout.get(1).get(0));
+	}
+
+	/**
+	 * This test makes sure that display connectors can be moved within the layout but also within the same column.
+	 */
+	@Test
+	public void testSameColumnMovement() {
+		// Create the necessary components
+		final MIAnalysisMetaModelFactory factory = MIAnalysisMetaModelFactory.eINSTANCE;
+		final MIProject project = factory.createProject();
+
+		final CockpitLayout cockpitLayout = new CockpitLayout(project, null, 1);
+
+		final MIView view = factory.createView();
+
+		final MIDisplayConnector displayConnector1 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector2 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector3 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector4 = factory.createDisplayConnector();
+
+		// Add everything to the cockpit layout
+		cockpitLayout.addView(view);
+
+		cockpitLayout.addDisplayConnector(view, displayConnector1, 0);
+		cockpitLayout.addDisplayConnector(view, displayConnector2, 0);
+		cockpitLayout.addDisplayConnector(view, displayConnector3, 0);
+		cockpitLayout.addDisplayConnector(view, displayConnector4, 0);
+
+		// Now move a display connector
+		cockpitLayout.moveDisplayConnector(view, displayConnector4, 0, 0, 0);
+
+		// Now get and check the layout
+		final List<List<MIDisplayConnector>> layout = cockpitLayout.getCurrentLayout(view);
+
+		Assert.assertEquals("Invalid layout", 1, layout.size());
+
+		Assert.assertEquals("Invalid layout", 4, layout.get(0).size());
+
+		Assert.assertEquals("Invalid layout", displayConnector1, layout.get(0).get(1));
+		Assert.assertEquals("Invalid layout", displayConnector2, layout.get(0).get(2));
+		Assert.assertEquals("Invalid layout", displayConnector3, layout.get(0).get(3));
+		Assert.assertEquals("Invalid layout", displayConnector4, layout.get(0).get(0));
+	}
+
+	/**
+	 * This test makes sure that display connectors can be removed from the layout.
+	 */
+	@Test
+	public void testDisplayConnectorRemoving() {
+		// Create the necessary components
+		final MIAnalysisMetaModelFactory factory = MIAnalysisMetaModelFactory.eINSTANCE;
+		final MIProject project = factory.createProject();
+
+		final CockpitLayout cockpitLayout = new CockpitLayout(project, null, 2);
+
+		final MIView view = factory.createView();
+
+		final MIDisplayConnector displayConnector1 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector2 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector3 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector4 = factory.createDisplayConnector();
+
+		// Add everything to the cockpit layout
+		cockpitLayout.addView(view);
+
+		cockpitLayout.addDisplayConnector(view, displayConnector1, 0);
+		cockpitLayout.addDisplayConnector(view, displayConnector2, 0);
+		cockpitLayout.addDisplayConnector(view, displayConnector3, 1);
+		cockpitLayout.addDisplayConnector(view, displayConnector4, 1);
+
+		// Now remove a display connector
+		cockpitLayout.removeDisplayConnector(view, displayConnector3);
+
+		// Now get and check the layout
+		final List<List<MIDisplayConnector>> layout = cockpitLayout.getCurrentLayout(view);
+
+		Assert.assertEquals("Invalid layout", 2, layout.size());
+
+		Assert.assertEquals("Invalid layout", 2, layout.get(0).size());
+		Assert.assertEquals("Invalid layout", 1, layout.get(1).size());
+
+		Assert.assertEquals("Invalid layout", displayConnector1, layout.get(0).get(0));
+		Assert.assertEquals("Invalid layout", displayConnector2, layout.get(0).get(1));
+		Assert.assertEquals("Invalid layout", displayConnector4, layout.get(1).get(0));
+	}
+
+	/**
+	 * This test makes sure that views can be removed from the layout.
+	 */
+	@Test
+	public void testViewsRemoving() {
+		// Create the necessary components
+		final MIAnalysisMetaModelFactory factory = MIAnalysisMetaModelFactory.eINSTANCE;
+		final MIProject project = factory.createProject();
+
+		final CockpitLayout cockpitLayout = new CockpitLayout(project, null, 2);
+
+		final MIView view1 = factory.createView();
+		final MIView view2 = factory.createView();
+		final MIDisplayConnector displayConnector1 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector2 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector3 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector4 = factory.createDisplayConnector();
+
+		// Add everything to the cockpit layout
+		cockpitLayout.addView(view1);
+		cockpitLayout.addView(view2);
+
+		cockpitLayout.addDisplayConnector(view1, displayConnector1, 0);
+		cockpitLayout.addDisplayConnector(view1, displayConnector2, 0);
+		cockpitLayout.addDisplayConnector(view1, displayConnector3, 1);
+
+		cockpitLayout.addDisplayConnector(view2, displayConnector4, 0);
+
+		// Now remove a view
+		cockpitLayout.removeView(view1);
+
+		// Now get and check the layout
+		final List<List<MIDisplayConnector>> layout2 = cockpitLayout.getCurrentLayout(view2);
+
+		Assert.assertEquals("Invalid layout", 2, layout2.size());
+
+		Assert.assertEquals("Invalid layout", 1, layout2.get(0).size());
+		Assert.assertEquals("Invalid layout", 0, layout2.get(1).size());
+
+		Assert.assertEquals("Invalid layout", displayConnector4, layout2.get(0).get(0));
+
+		// The following should throw an error
+		try {
+			cockpitLayout.getCurrentLayout(view1);
+			Assert.fail("Invalid layout");
+		} catch (final NullPointerException ex) { // NOPMD (JUnit Test)
+		}
+	}
+
+	/**
+	 * This test makes sure that the layout can be serialized and deserialized.
+	 */
+	@Test
+	public void testSerialization() {
+		// Create the necessary components
+		final MIAnalysisMetaModelFactory factory = MIAnalysisMetaModelFactory.eINSTANCE;
+		final MIProject project = factory.createProject();
+
+		final CockpitLayout cockpitLayout = new CockpitLayout(project, null, 2);
+
+		final MIView view1 = factory.createView();
+		final MIView view2 = factory.createView();
+		final MIDisplayConnector displayConnector1 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector2 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector3 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector4 = factory.createDisplayConnector();
+
+		view1.getDisplayConnectors().add(displayConnector1);
+		view1.getDisplayConnectors().add(displayConnector2);
+		view1.getDisplayConnectors().add(displayConnector3);
+
+		view2.getDisplayConnectors().add(displayConnector4);
+
+		project.getViews().add(view1);
+		project.getViews().add(view2);
+
+		// Add everything to the cockpit layout
+		cockpitLayout.addView(view1);
+		cockpitLayout.addView(view2);
+
+		cockpitLayout.addDisplayConnector(view1, displayConnector1, 0);
+		cockpitLayout.addDisplayConnector(view1, displayConnector2, 0);
+		cockpitLayout.addDisplayConnector(view1, displayConnector3, 1);
+
+		cockpitLayout.addDisplayConnector(view2, displayConnector4, 0);
+
+		// Now serialize and deserialize the layout
+		final CockpitLayout cockpitLayout2 = new CockpitLayout(project, cockpitLayout.serializeToString(), 2);
+
+		// Now get and check the layout
+		final List<List<MIDisplayConnector>> layout1 = cockpitLayout2.getCurrentLayout(view1);
+		final List<List<MIDisplayConnector>> layout2 = cockpitLayout2.getCurrentLayout(view2);
+
+		Assert.assertEquals("Invalid layout", 2, layout1.size());
+		Assert.assertEquals("Invalid layout", 2, layout2.size());
+
+		Assert.assertEquals("Invalid layout", 2, layout1.get(0).size());
+		Assert.assertEquals("Invalid layout", 1, layout1.get(1).size());
+
+		Assert.assertEquals("Invalid layout", 1, layout2.get(0).size());
+		Assert.assertEquals("Invalid layout", 0, layout2.get(1).size());
+
+		Assert.assertEquals("Invalid layout", displayConnector1, layout1.get(0).get(0));
+		Assert.assertEquals("Invalid layout", displayConnector2, layout1.get(0).get(1));
+		Assert.assertEquals("Invalid layout", displayConnector3, layout1.get(1).get(0));
+		Assert.assertEquals("Invalid layout", displayConnector4, layout2.get(0).get(0));
+	}
+
+	/**
+	 * This test makes sure that the class handles empty layouts correctly.
+	 */
+	@Test
+	public void testEmptyLayout() {
+		// Create the necessary components
+		final MIAnalysisMetaModelFactory factory = MIAnalysisMetaModelFactory.eINSTANCE;
+		final MIProject project = factory.createProject();
+
+		final MIView view1 = factory.createView();
+		final MIView view2 = factory.createView();
+		final MIDisplayConnector displayConnector1 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector2 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector3 = factory.createDisplayConnector();
+		final MIDisplayConnector displayConnector4 = factory.createDisplayConnector();
+
+		view1.getDisplayConnectors().add(displayConnector1);
+		view1.getDisplayConnectors().add(displayConnector2);
+		view1.getDisplayConnectors().add(displayConnector3);
+
+		view2.getDisplayConnectors().add(displayConnector4);
+
+		project.getViews().add(view1);
+		project.getViews().add(view2);
+
+		// Let the class load the project without layout
+		final CockpitLayout cockpitLayout = new CockpitLayout(project, null, 2);
+
+		// Now get and check the layout
+		final List<List<MIDisplayConnector>> layout1 = cockpitLayout.getCurrentLayout(view1);
+		final List<List<MIDisplayConnector>> layout2 = cockpitLayout.getCurrentLayout(view2);
+
+		Assert.assertEquals("Invalid layout", 2, layout1.size());
+		Assert.assertEquals("Invalid layout", 2, layout2.size());
+
+		Assert.assertEquals("Invalid layout", 3, layout1.get(0).size());
+		Assert.assertEquals("Invalid layout", 0, layout1.get(1).size());
+
+		Assert.assertEquals("Invalid layout", 1, layout2.get(0).size());
+		Assert.assertEquals("Invalid layout", 0, layout2.get(1).size());
+
+		Assert.assertEquals("Invalid layout", displayConnector1, layout1.get(0).get(0));
+		Assert.assertEquals("Invalid layout", displayConnector2, layout1.get(0).get(1));
+		Assert.assertEquals("Invalid layout", displayConnector3, layout1.get(0).get(2));
+		Assert.assertEquals("Invalid layout", displayConnector4, layout2.get(0).get(0));
+
+	}
+}