From e6258e8b0ad4996d32212010bdcbf00b8ec7c661 Mon Sep 17 00:00:00 2001
From: Nils Christian Ehmke <nie@informatik.uni-kiel.de>
Date: Sat, 8 Sep 2012 11:00:10 +0200
Subject: [PATCH] Continued with the usage of the correct project-classloaders.

---
 .../Bookstore-Example/Bookstore-Example.kax   |   5 +
 .../webgui/beans/view/CurrentCockpitBean.java |  37 +-
 .../beans/view/CurrentControllerBean.java     |  34 +-
 .../java/kieker/webgui/common/ACManager.java  | 405 +++---------------
 .../java/kieker/webgui/common/Analysis.java   | 261 +++++++++++
 .../common/ClassAndMethodContainer.java       | 351 ++++++++++++++-
 .../java/kieker/webgui/common/Triple.java     | 130 ------
 .../AnalysisAlreadyInstantiatedException.java |  51 +++
 .../AnalysisAlreadyStartedException.java      |  55 +++
 .../AnalysisInstantiationException.java       |  56 +++
 ....java => AnalysisNotStartedException.java} |   6 +-
 11 files changed, 870 insertions(+), 521 deletions(-)
 create mode 100644 Kieker.WebGUI/src/main/java/kieker/webgui/common/Analysis.java
 delete mode 100644 Kieker.WebGUI/src/main/java/kieker/webgui/common/Triple.java
 create mode 100644 Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisAlreadyInstantiatedException.java
 create mode 100644 Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisAlreadyStartedException.java
 create mode 100644 Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisInstantiationException.java
 rename Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/{AnalysisNotRunningException.java => AnalysisNotStartedException.java} (89%)

diff --git a/Kieker.WebGUI/bin/data/Bookstore-Example/Bookstore-Example.kax b/Kieker.WebGUI/bin/data/Bookstore-Example/Bookstore-Example.kax
index cf369d16..27ecb97a 100644
--- a/Kieker.WebGUI/bin/data/Bookstore-Example/Bookstore-Example.kax
+++ b/Kieker.WebGUI/bin/data/Bookstore-Example/Bookstore-Example.kax
@@ -39,4 +39,9 @@
   </plugins>
   <dependencies filePath="BookstoreApplication.jar"/>
   <dependencies filePath="commons-cli-1.2.jar"/>
+  <views name="My View" description="Some amazing view.">
+    <displayConnectors name="Valid Counter Display" display="//@plugins.5/@displays.0"/>
+    <displayConnectors name="Global Counter Display" display="//@plugins.4/@displays.0"/>
+    <displayConnectors name="Invalid Counter Display" display="//@plugins.3/@displays.0"/>
+  </views>
 </Project>
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitBean.java
index 868468ba..f9039d87 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitBean.java
@@ -20,20 +20,23 @@
 
 package kieker.webgui.beans.view;
 
+import java.lang.reflect.InvocationTargetException;
+
 import javax.faces.bean.ManagedBean;
 import javax.faces.bean.ManagedProperty;
 import javax.faces.bean.ViewScoped;
 import javax.faces.context.FacesContext;
 
-import kieker.analysis.display.AbstractDisplay;
 import kieker.analysis.display.HtmlText;
 import kieker.analysis.display.Image;
-import kieker.analysis.display.PlainText;
 import kieker.analysis.model.analysisMetaModel.MIProject;
 import kieker.analysis.model.analysisMetaModel.MIView;
 import kieker.webgui.beans.application.ProjectsBean;
 import kieker.webgui.common.ACManager;
+import kieker.webgui.common.ClassAndMethodContainer;
+import kieker.webgui.common.FSManager;
 import kieker.webgui.common.Global;
+import kieker.webgui.common.exception.ProjectLoadException;
 
 /**
  * The {@link CurrentCockpitBean} contains the necessary data behind an instance of the cockpit. It provides methods to read the state of the currently
@@ -64,6 +67,8 @@ public class CurrentCockpitBean {
 	@ManagedProperty(value = "#{projectsBean}")
 	private ProjectsBean projectsBean;
 
+	private ClassAndMethodContainer classAndMethodContainer;
+
 	/**
 	 * Creates a new instance of this class.
 	 */
@@ -121,13 +126,19 @@ public class CurrentCockpitBean {
 	/**
 	 * 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
 	 * JSF.</b>
+	 * 
+	 * @throws ProjectLoadException
 	 */
-	public void initalize() {
+	public void initalize() throws ProjectLoadException {
 		synchronized (this) {
 			// Make sure that the initialization will only be done for the init request.
 			if (!FacesContext.getCurrentInstance().isPostback() && (this.projectsBean != null)) {
 				// Remember the given parameters
 				this.project = this.projectsBean.openProject(this.projectName);
+
+				if (this.project != null) {
+					this.classAndMethodContainer = new ClassAndMethodContainer(FSManager.getInstance().getClassLoader(this.projectName));
+				}
 			}
 		}
 	}
@@ -152,18 +163,26 @@ public class CurrentCockpitBean {
 	 *         does exist, but the return content is not plain text, null will be returned.
 	 */
 	public String updatePlainTextDisplay(final String displayName) {
-		final String result;
+		String result;
 
 		synchronized (this) {
 			if ((this.activeView != null) && (this.projectName != null)) {
-				final AbstractDisplay displayObj = ACManager.getInstance().getDisplay(this.projectName, this.activeView.getName(), displayName);
+				final Object displayObj = ACManager.getInstance().getDisplay(this.projectName, this.activeView.getName(), displayName);
 				if (displayObj == null) {
 					// The display does not exist
 					result = "N/A";
 				} else {
-					if (displayObj instanceof PlainText) {
+					if (this.classAndMethodContainer.getPlainTextClass().isAssignableFrom(displayObj.getClass())) {
 						// The display exists and is valid
-						result = ((PlainText) displayObj).getText();
+						try {
+							result = (String) (this.classAndMethodContainer.getPlainTextgetTextMethod().invoke(displayObj, new Object[0]));
+						} catch (final IllegalAccessException e) {
+							result = "Error";
+						} catch (final IllegalArgumentException e) {
+							result = "Error";
+						} catch (final InvocationTargetException e) {
+							result = "Error";
+						}
 					} else {
 						// The display exists, but is not valid
 						result = null;
@@ -191,7 +210,7 @@ public class CurrentCockpitBean {
 
 		synchronized (this) {
 			if ((this.activeView != null) && (this.projectName != null)) {
-				final AbstractDisplay displayObj = ACManager.getInstance().getDisplay(this.projectName, this.activeView.getName(), displayName);
+				final Object displayObj = ACManager.getInstance().getDisplay(this.projectName, this.activeView.getName(), displayName);
 				if (displayObj == null) {
 					// The display does not exist
 					result = "N/A";
@@ -226,7 +245,7 @@ public class CurrentCockpitBean {
 
 		synchronized (this) {
 			if ((this.activeView != null) && (this.projectName != null)) {
-				final AbstractDisplay displayObj = ACManager.getInstance().getDisplay(this.projectName, this.activeView.getName(), displayName);
+				final Object displayObj = ACManager.getInstance().getDisplay(this.projectName, this.activeView.getName(), displayName);
 				if (displayObj == null) {
 					// The display does not exist
 					result = "N/A";
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentControllerBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentControllerBean.java
index 860c94af..a0ca7527 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentControllerBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentControllerBean.java
@@ -20,8 +20,6 @@
 
 package kieker.webgui.beans.view;
 
-import java.io.IOException;
-
 import javax.faces.application.FacesMessage;
 import javax.faces.application.FacesMessage.Severity;
 import javax.faces.bean.ManagedBean;
@@ -30,17 +28,17 @@ import javax.faces.bean.ViewScoped;
 import javax.faces.context.FacesContext;
 
 import kieker.analysis.AnalysisController;
-import kieker.analysis.exception.AnalysisConfigurationException;
 import kieker.analysis.model.analysisMetaModel.MIProject;
 import kieker.common.logging.Log;
 import kieker.common.logging.LogFactory;
 import kieker.webgui.beans.application.ProjectsBean;
 import kieker.webgui.common.ACManager;
 import kieker.webgui.common.Global;
+import kieker.webgui.common.exception.AnalysisAlreadyInstantiatedException;
+import kieker.webgui.common.exception.AnalysisAlreadyStartedException;
+import kieker.webgui.common.exception.AnalysisInstantiationException;
 import kieker.webgui.common.exception.AnalysisNotInstantiatedException;
-import kieker.webgui.common.exception.AnalysisNotRunningException;
-import kieker.webgui.common.exception.ProjectAlreadyStartedException;
-import kieker.webgui.common.exception.ProjectStillRunningException;
+import kieker.webgui.common.exception.AnalysisNotStartedException;
 
 /**
  * /**
@@ -166,9 +164,9 @@ public class CurrentControllerBean {
 			synchronized (this) {
 				ACManager.getInstance().startAnalysisController(this.projectName);
 			}
-		} catch (final ProjectAlreadyStartedException ex) {
-			CurrentControllerBean.LOG.info("The analysis is already running.", ex);
-			CurrentControllerBean.showMessage(FacesMessage.SEVERITY_WARN, "The analysis is already running.");
+		} catch (final AnalysisAlreadyStartedException ex) {
+			CurrentControllerBean.LOG.info("The analysis has already been started.", ex);
+			CurrentControllerBean.showMessage(FacesMessage.SEVERITY_WARN, "The analysis has already been started.");
 		} catch (final AnalysisNotInstantiatedException ex) {
 			CurrentControllerBean.LOG.info("The analysis has not been instantiated yet.", ex);
 			CurrentControllerBean.showMessage(FacesMessage.SEVERITY_WARN, "The analysis has not been instantiated yet.");
@@ -183,11 +181,9 @@ public class CurrentControllerBean {
 			synchronized (this) {
 				ACManager.getInstance().stopAnalysisController(this.projectName);
 			}
-		} catch (final AnalysisNotRunningException ex) {
+		} catch (final AnalysisNotStartedException ex) {
 			CurrentControllerBean.LOG.info("The analysis has not been started yet.", ex);
 			CurrentControllerBean.showMessage(FacesMessage.SEVERITY_WARN, "The analysis has not been started yet.");
-		} catch (final InterruptedException ex) {
-			CurrentControllerBean.LOG.error("Unknown interrupted exception.", ex);
 		}
 	}
 
@@ -199,18 +195,12 @@ public class CurrentControllerBean {
 			synchronized (this) {
 				ACManager.getInstance().instantiateAnalysisController(this.projectName);
 			}
-		} catch (final NullPointerException ex) { // NOPMD (Exception is explicitly thrown)
-			CurrentControllerBean.LOG.error("An error occurred while instantiating the analysis.", ex);
-			CurrentControllerBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occurred while instantiating the analysis.");
-		} catch (final AnalysisConfigurationException ex) {
-			CurrentControllerBean.LOG.error("An error occurred while instantiating the analysis.", ex);
-			CurrentControllerBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occurred while instantiating the analysis.");
-		} catch (final IOException ex) {
+		} catch (final AnalysisAlreadyInstantiatedException ex) {
+			CurrentControllerBean.LOG.error("The analysis has already been instantiated.", ex);
+			CurrentControllerBean.showMessage(FacesMessage.SEVERITY_ERROR, "The analysis has already been instantiated.");
+		} catch (final AnalysisInstantiationException ex) {
 			CurrentControllerBean.LOG.error("An error occurred while instantiating the analysis.", ex);
 			CurrentControllerBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occurred while instantiating the analysis.");
-		} catch (final ProjectStillRunningException ex) {
-			CurrentControllerBean.LOG.info("The analysis is still running.", ex);
-			CurrentControllerBean.showMessage(FacesMessage.SEVERITY_ERROR, "The analysis is still running.");
 		}
 	}
 
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java
index 973d3956..7ca07997 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java
@@ -21,34 +21,18 @@
 package kieker.webgui.common;
 
 import java.io.IOException;
-import java.lang.Thread.State;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 import kieker.analysis.AnalysisController;
-import kieker.analysis.AnalysisController.AnalysisControllerWithMapping;
-import kieker.analysis.AnalysisController.STATE;
-import kieker.analysis.display.AbstractDisplay;
-import kieker.analysis.display.HtmlText;
-import kieker.analysis.display.Image;
-import kieker.analysis.display.PlainText;
-import kieker.analysis.display.annotation.Display;
-import kieker.analysis.exception.AnalysisConfigurationException;
-import kieker.analysis.model.analysisMetaModel.MIDisplayConnector;
-import kieker.analysis.model.analysisMetaModel.MIPlugin;
 import kieker.analysis.model.analysisMetaModel.MIProject;
-import kieker.analysis.model.analysisMetaModel.MIView;
-import kieker.analysis.plugin.AbstractPlugin;
 import kieker.common.logging.Log;
 import kieker.common.logging.LogFactory;
+import kieker.webgui.common.exception.AnalysisAlreadyInstantiatedException;
+import kieker.webgui.common.exception.AnalysisAlreadyStartedException;
+import kieker.webgui.common.exception.AnalysisInstantiationException;
 import kieker.webgui.common.exception.AnalysisNotInstantiatedException;
-import kieker.webgui.common.exception.AnalysisNotRunningException;
+import kieker.webgui.common.exception.AnalysisNotStartedException;
 import kieker.webgui.common.exception.ProjectAlreadyStartedException;
-import kieker.webgui.common.exception.ProjectStillRunningException;
 
 /**
  * This manager is responsible for the currently used and running instances of {@code AnalysisController}. It supplies methods to check the states of analysis,
@@ -57,16 +41,12 @@ import kieker.webgui.common.exception.ProjectStillRunningException;
  * @author Nils Christian Ehmke
  * @version 1.0
  */
-// TODO How to differ between views and displays with same names?
-public final class ACManager { // NOCS (Class Data Abstraction Coupling)
+// TODO Make this class threadsafe!!
+public final class ACManager {
 	/**
 	 * This is the log for errors, exceptions etc.
 	 */
 	private static final Log LOG = LogFactory.getLog(ACManager.class);
-	/**
-	 * This is the maximal time the application will wait for an analysis thread to be terminated.
-	 */
-	private static final long MAX_THREAD_WAIT_TIME_MS = 1000;
 	/**
 	 * This is the singleton instance of this class.
 	 */
@@ -75,8 +55,7 @@ public final class ACManager { // NOCS (Class Data Abstraction Coupling)
 	 * This list contains the current analysis controllers and their corresponding threads. Not every project does have a controller, but every project can have
 	 * maximal one.
 	 */
-	private final ConcurrentHashMap<String, Triple<AnalysisController, Thread, UpdateDisplaysThread>> analysisController = new ConcurrentHashMap<String,
-			Triple<AnalysisController, Thread, UpdateDisplaysThread>>();
+	private final ConcurrentHashMap<String, Analysis> analyses = new ConcurrentHashMap<String, Analysis>();
 
 	/**
 	 * Creates a new instance of this class.
@@ -99,24 +78,18 @@ public final class ACManager { // NOCS (Class Data Abstraction Coupling)
 	 * 
 	 * @param project
 	 *            The project to be stopped.
-	 * @throws AnalysisNotRunningException
+	 * @throws AnalysisNotStartedException
 	 *             If the analysis is not running or has not yet been initialized.
 	 * @throws InterruptedException
 	 *             If the current thread has somehow been interrupted while waiting for the existing analysis thread.
 	 */
-	public void stopAnalysisController(final String project) throws AnalysisNotRunningException, InterruptedException {
-		final Triple<AnalysisController, Thread, UpdateDisplaysThread> currController = this.analysisController.get(project);
-		try {
-			synchronized (currController) {
-				// Try to stop the analysis
-				currController.getFst().terminate();
-				currController.getThd().terminate();
-				currController.getSnd().join(ACManager.MAX_THREAD_WAIT_TIME_MS);
-				currController.getThd().join(ACManager.MAX_THREAD_WAIT_TIME_MS);
-			}
-		} catch (final NullPointerException ex) { // NOPMD
-			ACManager.LOG.info("Analysis is not running.", ex);
-			throw new AnalysisNotRunningException(); // NOPMD
+	public void stopAnalysisController(final String project) throws AnalysisNotStartedException {
+		final Analysis analysis = this.analyses.get(project);
+
+		if (analysis != null) {
+			analysis.stop();
+		} else {
+			throw new AnalysisNotStartedException("The analysis has not been started yet.");
 		}
 	}
 
@@ -130,22 +103,13 @@ public final class ACManager { // NOCS (Class Data Abstraction Coupling)
 	 * @throws AnalysisNotInstantiatedException
 	 *             If the analysis has not yet been initialized.
 	 */
-	public void startAnalysisController(final String project) throws ProjectAlreadyStartedException, AnalysisNotInstantiatedException {
-		final Triple<AnalysisController, Thread, UpdateDisplaysThread> currController = this.analysisController.get(project);
-		// Is there an analysis after all?
-		try {
-			synchronized (currController) {
-				// Check whether this analysis has already been started - or is already dead.
-				if (currController.getSnd().getState() != State.NEW) {
-					throw new ProjectAlreadyStartedException();
-				}
-				// Otherwise start the analysis
-				currController.getSnd().start();
-				currController.getThd().start();
-			}
-		} catch (final NullPointerException ex) { // NOPMD (Generic exception)
-			ACManager.LOG.info("Analysis is not instantiated.", ex);
-			throw new AnalysisNotInstantiatedException(); // NOPMD
+	public void startAnalysisController(final String project) throws AnalysisAlreadyStartedException, AnalysisNotInstantiatedException {
+		final Analysis analysis = this.analyses.get(project);
+
+		if (analysis != null) {
+			analysis.start();
+		} else {
+			throw new AnalysisNotInstantiatedException("The analysis has not been initialized yet.");
 		}
 	}
 
@@ -157,21 +121,12 @@ public final class ACManager { // NOCS (Class Data Abstraction Coupling)
 	 *            The name of the project to be cleaned.
 	 */
 	public void cleanAnalysisController(final String project) {
-		final Triple<AnalysisController, Thread, UpdateDisplaysThread> currController = this.analysisController.get(project);
-		// Is there an analysis after all?
-		try {
-			synchronized (currController) {
-				this.stopAnalysisController(project);
-				this.analysisController.remove(project);
-			}
-		} catch (final NullPointerException ex) { // NOPMD
-			ACManager.LOG.info("Analysis is not instantiated.", ex);
-		} catch (final AnalysisNotRunningException ex) {
-			ACManager.LOG.info("Analysis is not running.", ex);
-		} catch (final InterruptedException ex) {
-			ACManager.LOG.info("Unexpected interrupted exception.", ex);
-		}
+		final Analysis analysis = this.analyses.get(project);
 
+		if (analysis != null) {
+			analysis.stop();
+			this.analyses.remove(project);
+		}
 	}
 
 	/**
@@ -179,38 +134,20 @@ public final class ACManager { // NOCS (Class Data Abstraction Coupling)
 	 * 
 	 * @param project
 	 *            The project whose analysis controller should be instantiated.
-	 * @throws NullPointerException
-	 *             If an error occurred while loading the project.
-	 * @throws AnalysisConfigurationException
-	 *             If the given configuration is somehow invalid.
-	 * @throws IOException
-	 *             If an error occurred while loading the project.
-	 * @throws ProjectStillRunningException
-	 *             If there exists already an analysis controller and is still running.
+	 * @throws AnalysisInstantiationException
 	 */
-	public void instantiateAnalysisController(final String project) throws NullPointerException, AnalysisConfigurationException, IOException,
-			ProjectStillRunningException {
-		final Triple<AnalysisController, Thread, UpdateDisplaysThread> newController = new Triple<AnalysisController, Thread, UpdateDisplaysThread>();
-		synchronized (newController) {
-			// Add the potential new project atomically
-			final Triple<AnalysisController, Thread, UpdateDisplaysThread> currController = this.analysisController.putIfAbsent(project, newController);
-			// We can just add a new controller if there wasn't an old one.
-			if (currController != null) {
-				throw new ProjectStillRunningException("The project with the name '" + project + "' is still running.");
-			}
-			final MIProject modelProject = FSManager.getInstance().openProject(project);
-			final ClassLoader classLoader = FSManager.getInstance().getClassLoader(project);
-			final AnalysisControllerWithMapping controller = AnalysisController.createAnalysisController(modelProject, classLoader);
-
-			// Create the necessary threads for the analysis
-			final Thread runningThread = new ControllerRunningThread(controller);
-			// runningThread.start();
+	public void instantiateAnalysisController(final String project) throws AnalysisAlreadyInstantiatedException, AnalysisInstantiationException {
+		try {
+			if (!this.analyses.containsKey(project)) {
+				final MIProject modelProject = FSManager.getInstance().openProject(project);
+				final ClassLoader classLoader = FSManager.getInstance().getClassLoader(project);
 
-			final UpdateDisplaysThread displayThread = new UpdateDisplaysThread(controller.getPluginMap(), modelProject);
-			// Put everything into our container
-			newController.setFst(controller.getController());
-			newController.setSnd(runningThread);
-			newController.setThd(displayThread);
+				this.analyses.put(project, new Analysis(classLoader, modelProject));
+			} else {
+				throw new AnalysisAlreadyInstantiatedException("The analysis has already been initialized.");
+			}
+		} catch (final IOException ex) {
+			throw new AnalysisInstantiationException("An IO-error occured while instantiating the analysis.", ex);
 		}
 	}
 
@@ -222,34 +159,11 @@ public final class ACManager { // NOCS (Class Data Abstraction Coupling)
 	 * @return The current state of the corresponding {@link AnalysisController} if it exists, '' otherwise.
 	 */
 	public String getAnalysisControllerStateString(final String project) {
-		final STATE controllerState = this.getAnalysisControllerState(project);
-		final String controllerStateString;
+		final Enum<?> state = this.getAnalysisControllerState(project);
 
-		if (controllerState == null) {
-			controllerStateString = "";
+		if (state != null) {
+			return state.toString();
 		} else {
-			controllerStateString = controllerState.toString();
-		}
-
-		return controllerStateString;
-	}
-
-	/**
-	 * Delivers the display object for the given display in the given view in the given project.
-	 * 
-	 * @param project
-	 *            The name of the project.
-	 * @param viewName
-	 *            The name of the view.
-	 * @param displayName
-	 *            The name of the display.
-	 * @return The display object if it exists, null otherwise.
-	 */
-	public AbstractDisplay getDisplay(final String project, final String viewName, final String displayName) {
-		try {
-			return this.analysisController.get(project).getThd().getDisplay(viewName, displayName);
-		} catch (final NullPointerException ex) { // NOPMD
-			ACManager.LOG.info("Invalid project, view or display.", ex);
 			return null;
 		}
 	}
@@ -261,232 +175,33 @@ public final class ACManager { // NOCS (Class Data Abstraction Coupling)
 	 *            The project whose state should be delivered.
 	 * @return The current state of the corresponding {@link AnalysisController} if it exists, null otherwise.
 	 */
-	public STATE getAnalysisControllerState(final String project) {
-		// If the given project is null, we return a null-state.
-		if (project == null) {
-			return null;
-		}
-		final Triple<AnalysisController, Thread, UpdateDisplaysThread> controller = this.analysisController.get(project);
+	public Enum<?> getAnalysisControllerState(final String project) {
+		final Analysis analysis = this.analyses.get(project);
 
-		final STATE controllerState;
-		if (controller == null) {
-			controllerState = null;
+		if (analysis != null) {
+			return analysis.getCurrentState();
 		} else {
-			synchronized (controller) {
-				if (controller.getFst() == null) {
-					controllerState = null;
-				} else {
-					controllerState = controller.getFst().getState();
-				}
-			}
-		}
-
-		return controllerState;
-	}
-
-	/**
-	 * This method delivers the current displays of the given project. They can be used to show the stored information but should <b>not</b> be modified.
-	 * 
-	 * @param projectName
-	 *            The name of the project whose displays should be delivered.
-	 * @return A list of pairs containing the displays and the name of them.
-	 */
-	public List<Pair<String, AbstractDisplay>> getCurrentDisplays(final String projectName) {
-		final List<Pair<String, AbstractDisplay>> result = new ArrayList<Pair<String, AbstractDisplay>>();
-
-		return result;
-	}
-
-	/**
-	 * This helper thread is responsible for running an instance of {@link AnalysisControllerWithMapping}.
-	 * 
-	 * @author Nils Christian Ehmke
-	 * @version 1.0
-	 */
-	private static class ControllerRunningThread extends Thread {
-		/**
-		 * The controller managed by this thread.
-		 */
-		private final AnalysisControllerWithMapping controller;
-
-		/**
-		 * Default constructor.
-		 * 
-		 * @param controller
-		 *            The controller to be managed by this thread.
-		 */
-		public ControllerRunningThread(final AnalysisControllerWithMapping controller) {
-			this.controller = controller;
-		}
-
-		@Override
-		public void run() {
-			try {
-				this.controller.getController().run();
-			} catch (final IllegalStateException ex) {
-				ACManager.LOG.error("An error occured while starting the analysis.", ex);
-				ex.printStackTrace();
-			} catch (final AnalysisConfigurationException ex) {
-				ACManager.LOG.error("An error occured while starting the analysis.", ex);
-				ex.printStackTrace();
-			}
+			return null;
 		}
 	}
 
 	/**
-	 * This helper thread is used to update the available displays of the given analysis at regular intervals. <b>Important:</b> If the interrupt-method of the
-	 * thread is being called, it will be terminated.
+	 * Delivers the display object for the given display in the given view in the given project.
 	 * 
-	 * @author Nils Christian Ehmke
-	 * @version 1.0
+	 * @param project
+	 *            The name of the project.
+	 * @param viewName
+	 *            The name of the view.
+	 * @param displayName
+	 *            The name of the display.
+	 * @return The display object if it exists, null otherwise.
 	 */
-	private static class UpdateDisplaysThread extends Thread {
-
-		/**
-		 * This is the time the thread waits between the updates.
-		 */
-		private static final long SLEEP_TIME_MS = 2 * 1000;
-		/**
-		 * The map between the instances of {@link MIPlugin} and {@link AbstractPlugin} within the running analysis instance.
-		 */
-		private final Map<MIPlugin, AbstractPlugin> myPluginMap;
-		/**
-		 * The model instance.
-		 */
-		private final MIProject myProject;
-		/**
-		 * The map containing all available display objects.
-		 */
-		private final Map<String, Map<String, AbstractDisplay>> displayObjects = new ConcurrentHashMap<String, Map<String, AbstractDisplay>>(); // NOPMD
-		/**
-		 * This map contains the mapping to get the methods to be called.
-		 */
-		private final Map<AbstractDisplay, Method> methodMap = new ConcurrentHashMap<AbstractDisplay, Method>(); // NOPMD (Use of concurrent hash map)
-		/**
-		 * The field determining whether the thread has been terminated or not. // (USeConcurrentHashMap)
-		 */
-		private volatile boolean terminated = false;
-
-		/**
-		 * Creates a new instance of this class using the given parameters.
-		 * 
-		 * @param pluginMap
-		 *            The map between the instances of {@link MIPlugin} and {@link AbstractPlugin} within the running analysis instance.
-		 * @param modelProject
-		 *            The model instance.
-		 */
-		public UpdateDisplaysThread(final Map<MIPlugin, AbstractPlugin> pluginMap, final MIProject modelProject) {
-			this.myPluginMap = pluginMap;
-			this.myProject = modelProject;
-
-			// Initialize the hashmaps and the necessary objects
-			for (final MIView view : this.myProject.getViews()) {
-				final Map<String, AbstractDisplay> viewMap = new ConcurrentHashMap<String, AbstractDisplay>(); // NOPMD (Use of concurrent hash map)
-				this.displayObjects.put(view.getName(), viewMap);
-				for (final MIDisplayConnector displayConnector : view.getDisplayConnectors()) {
-					final Method displayMethod = UpdateDisplaysThread.getDisplayMethod(this.myPluginMap.get(displayConnector.getDisplay().getParent()).getClass(),
-							displayConnector.getDisplay().getName());
-
-					// Make sure that the method really exists and that is has the correct parameters
-					if ((displayMethod != null) && (displayMethod.getParameterTypes().length == 1)) {
-						final Class<?> parameterType = displayMethod.getParameterTypes()[0];
-						final AbstractDisplay displayObject;
-						// Get the correct type
-						if (Image.class.isAssignableFrom(parameterType)) {
-							displayObject = new Image();
-						} else {
-							if (PlainText.class.isAssignableFrom(parameterType)) {
-								displayObject = new PlainText();
-							} else {
-								if (HtmlText.class.isAssignableFrom(parameterType)) {
-									displayObject = new HtmlText();
-								} else {
-									displayObject = null;
-								}
-							}
-						}
-						if (displayObject != null) {
-							viewMap.put(displayConnector.getName(), displayObject);
-							this.methodMap.put(displayObject, displayMethod);
-						}
-					}
-				}
-			}
-		}
-
-		/**
-		 * Delivers the correct method to be invoked for an update of the display.
-		 * 
-		 * @param clazz
-		 *            The class of the plugin.
-		 * @param displayName
-		 *            The name within the display-annotation.
-		 * @return The method instance.
-		 */
-		private static Method getDisplayMethod(final Class<? extends AbstractPlugin> clazz, final String displayName) {
-			final Method[] methods = clazz.getMethods();
-			for (final Method method : methods) {
-				final Display displayAnnot = method.getAnnotation(Display.class);
-				if ((displayAnnot != null) && displayAnnot.name().equals(displayName)) {
-					// We found the correct method
-					return method;
-				}
-			}
+	public Object getDisplay(final String project, final String viewName, final String displayName) {
+		final Analysis analysis = this.analyses.get(project);
+		if (analysis != null) {
+			return analysis.getDisplay(viewName, displayName);
+		} else {
 			return null;
 		}
-
-		/**
-		 * Terminates this thread.
-		 */
-		public void terminate() {
-			this.terminated = true;
-		}
-
-		/**
-		 * Delivers the display object for the given view and the given display.
-		 * 
-		 * @param viewName
-		 *            The name of the view.
-		 * @param displayName
-		 *            The name of the display in the view.
-		 * @return The object for the given display if it exists, null otherwise.
-		 */
-		public AbstractDisplay getDisplay(final String viewName, final String displayName) {
-			return this.displayObjects.get(viewName).get(displayName);
-		}
-
-		@Override
-		public void run() {
-			// Run until we have been interrupted
-			while (!this.terminated) {
-				for (final MIView view : this.myProject.getViews()) {
-					final Map<String, AbstractDisplay> viewMap = this.displayObjects.get(view.getName()); // NOPMD (Use of concurrent hash map)
-					for (final MIDisplayConnector displayConnector : view.getDisplayConnectors()) {
-						final AbstractDisplay displayObject = viewMap.get(displayConnector.getName());
-						final AbstractPlugin pluginObject = this.myPluginMap.get(displayConnector.getDisplay().getParent());
-						// Update the display object
-						try {
-							this.methodMap.get(displayObject).invoke(pluginObject, displayObject);
-						} catch (final IllegalAccessException ex) {
-							ACManager.LOG.error("An error occured while updating the display.", ex);
-						} catch (final IllegalArgumentException ex) {
-							ACManager.LOG.error("An error occured while updating the display.", ex);
-						} catch (final InvocationTargetException ex) {
-							ACManager.LOG.error("An error occured while updating the display.", ex);
-						} catch (final NullPointerException ex) { // NOPMD
-							ACManager.LOG.error("An error occured while updating the display.", ex);
-						}
-					}
-				}
-
-				// Wait a little bit.
-				try {
-					Thread.sleep(UpdateDisplaysThread.SLEEP_TIME_MS);
-				} catch (final InterruptedException ex) {
-					// We have been interrupted. Exit the thread
-					return;
-				}
-			}
-		}
 	}
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/Analysis.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/Analysis.java
new file mode 100644
index 00000000..614566c3
--- /dev/null
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/Analysis.java
@@ -0,0 +1,261 @@
+package kieker.webgui.common;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.annotation.PostConstruct;
+
+import kieker.analysis.model.analysisMetaModel.MIDisplayConnector;
+import kieker.analysis.model.analysisMetaModel.MIProject;
+import kieker.analysis.model.analysisMetaModel.MIView;
+import kieker.analysis.plugin.AbstractPlugin;
+import kieker.common.logging.Log;
+import kieker.common.logging.LogFactory;
+import kieker.webgui.common.exception.AnalysisAlreadyStartedException;
+import kieker.webgui.common.exception.AnalysisInstantiationException;
+import kieker.webgui.common.exception.ProjectLoadException;
+
+// TODO AnalysisController, Thread etc. have to be initialized via the class loader as well
+public class Analysis {
+	/**
+	 * This is the log for errors, exceptions etc.
+	 */
+	private static final Log LOG = LogFactory.getLog(Analysis.class);
+	private static final long MAX_THREAD_WAIT_TIME_MS = 1000;
+	private final ClassAndMethodContainer classAndMethodContainer;
+	private final MIProject modelProject;
+	private final Object analysisController;
+	private final Object analysisControllerThread;
+	private final UpdateDisplaysThread updateDisplaysThread;
+
+	public Analysis(final ClassLoader classLoader, final MIProject modelProject) throws AnalysisInstantiationException {
+		try {
+			this.modelProject = modelProject;
+			this.classAndMethodContainer = new ClassAndMethodContainer(classLoader);
+
+			final Method createMethod = this.classAndMethodContainer.getAnalysisControllerCreateAnalysisController();
+			final Object controllerAndMapping = ClassAndMethodContainer.invokeClassMethod(createMethod, null, this.modelProject, classLoader);
+			this.analysisController = ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getAnalysisControllerWithMappingGetController(),
+					controllerAndMapping, null);
+			this.analysisControllerThread = ClassAndMethodContainer.invokeConstructor(this.classAndMethodContainer.getAnalysisControllerThreadConstructor(),
+					this.analysisController);
+			this.updateDisplaysThread = new UpdateDisplaysThread(ClassAndMethodContainer.invokeMethod(
+					this.classAndMethodContainer.getAnalysisControllerWithMappingGetMapping(), controllerAndMapping, null));
+			if ((this.analysisController == null) || (this.analysisControllerThread == null)) {
+				throw new AnalysisInstantiationException("An error occured while instantiating the analysis.");
+			}
+		} catch (final ProjectLoadException ex) {
+			throw new AnalysisInstantiationException("An error occured while instantiating the analysis.", ex);
+		} catch (final NullPointerException ex) {
+			throw new AnalysisInstantiationException("An error occured while instantiating the analysis.", ex);
+		}
+	}
+
+	public void start() throws AnalysisAlreadyStartedException {
+		synchronized (this) {
+			try {
+				this.classAndMethodContainer.getAnalysisControllerThreadStart().invoke(this.analysisControllerThread, new Object[0]);
+				this.updateDisplaysThread.start();
+			} catch (final IllegalThreadStateException ex) {
+				throw new AnalysisAlreadyStartedException("The analysis has already been started once. It has to be reinitialized to be runnable again.", ex);
+			} catch (final IllegalAccessException ex) {
+				Analysis.LOG.error("An error occured during a reflection method call.", ex);
+			} catch (final IllegalArgumentException ex) {
+				Analysis.LOG.error("An error occured during a reflection method call.", ex);
+			} catch (final InvocationTargetException ex) {
+				throw new AnalysisAlreadyStartedException("The analysis has already been started once. It has to be reinitialized to be runnable again.", ex);
+			}
+		}
+
+	}
+
+	public void stop() {
+		synchronized (this) {
+			try {
+				this.classAndMethodContainer.getAnalysisControllerThreadTerminate().invoke(this.analysisControllerThread, new Object[0]);
+				this.updateDisplaysThread.terminate();
+
+				this.classAndMethodContainer.getAnalysisControllerThreadJoin().invoke(this.analysisControllerThread, Analysis.MAX_THREAD_WAIT_TIME_MS);
+				this.updateDisplaysThread.join(Analysis.MAX_THREAD_WAIT_TIME_MS);
+			} catch (final InterruptedException ex) {
+				// Log the exception, but don't handle it further
+				Analysis.LOG.info("An interrupted exception occured.", ex);
+			} catch (final IllegalAccessException ex) {
+				Analysis.LOG.error("An error occured during a reflection method call.", ex);
+			} catch (final IllegalArgumentException ex) {
+				Analysis.LOG.error("An error occured during a reflection method call.", ex);
+			} catch (final InvocationTargetException ex) {
+				Analysis.LOG.error("An error occured during a reflection method call.", ex);
+			}
+		}
+	}
+
+	public Enum<?> getCurrentState() {
+		synchronized (this) {
+			return (Enum<?>) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getAnalysisControllerGetState(), this.analysisController, null);
+		}
+	}
+
+	public Object getDisplay(final String viewName, final String displayName) {
+		return this.updateDisplaysThread.getDisplay(viewName, displayName);
+	}
+
+	/**
+	 * This manager is responsible for the currently used and running instances of {@code AnalysisController}. It supplies methods to check the states of analysis,
+	 * instantiate, start and to stop them.
+	 * 
+	 * @author Nils Christian Ehmke
+	 * @version 1.0
+	 */
+	private class UpdateDisplaysThread extends Thread {
+
+		/**
+		 * This is the time the thread waits between the updates.
+		 */
+		private static final long SLEEP_TIME_MS = 2 * 1000;
+		private final Object pluginMap;
+		/**
+		 * The map containing all available display objects.
+		 */
+		private final Map<String, Map<String, Object>> displayObjects = new ConcurrentHashMap<String, Map<String, Object>>(); // NOPMD
+		/**
+		 * This map contains the mapping to get the methods to be called.
+		 */
+		private final Map<Object, Method> methodMap = new ConcurrentHashMap<Object, Method>(); // NOPMD (Use of concurrent hash map)
+		/**
+		 * The field determining whether the thread has been terminated or not. // (USeConcurrentHashMap)
+		 */
+		private volatile boolean terminated = false;
+
+		public UpdateDisplaysThread(final Object object) {
+			this.pluginMap = object;
+		}
+
+		@PostConstruct
+		private void initialize() {
+			// Initialize the hashmaps and the necessary objects
+			for (final MIView view : Analysis.this.modelProject.getViews()) {
+				final Map<String, Object> viewMap = new ConcurrentHashMap<String, Object>(); // NOPMD (Use of concurrent hash map)
+				this.displayObjects.put(view.getName(), viewMap);
+				for (final MIDisplayConnector displayConnector : view.getDisplayConnectors()) {
+					// final Method displayMethod = this.getDisplayMethod(this.pluginMap.get(displayConnector.getDisplay().getParent()).getClass(),
+					// displayConnector.getDisplay().getName());
+
+					// Make sure that the method really exists and that is has the correct parameters
+					/*
+					 * if ((displayMethod != null) && (displayMethod.getParameterTypes().length == 1)) {
+					 * final Class<?> parameterType = displayMethod.getParameterTypes()[0];
+					 * final Object displayObject;
+					 * // Get the correct type
+					 * if (Analysis.this.classAndMethodContainer.getImageClass().isAssignableFrom(parameterType)) {
+					 * displayObject = new Image();
+					 * } else {
+					 * if (Analysis.this.classAndMethodContainer.getPlainTextClass().isAssignableFrom(parameterType)) {
+					 * displayObject = new PlainText();
+					 * } else {
+					 * if (Analysis.this.classAndMethodContainer.getHtmlTextClass().isAssignableFrom(parameterType)) {
+					 * displayObject = new HtmlText();
+					 * } else {
+					 * displayObject = null;
+					 * }
+					 * }
+					 * }
+					 * if (displayObject != null) {
+					 * viewMap.put(displayConnector.getName(), displayObject);
+					 * this.methodMap.put(displayObject, displayMethod);
+					 * }
+					 * }
+					 */
+				}
+			}
+		}
+
+		/**
+		 * Delivers the correct method to be invoked for an update of the display.
+		 * 
+		 * @param clazz
+		 *            The class of the plugin.
+		 * @param displayName
+		 *            The name within the display-annotation.
+		 * @return The method instance.
+		 */
+		private Method getDisplayMethod(final Class<? extends AbstractPlugin> clazz, final String displayName) {
+			final Method[] methods = clazz.getMethods();
+			for (final Method method : methods) {
+				try {
+					final Annotation displayAnnot = method.getAnnotation(Analysis.this.classAndMethodContainer.getDisplayAnnotationClass());
+					if ((displayAnnot != null)
+							&& (Analysis.this.classAndMethodContainer.getDisplayNameMethod().invoke(displayAnnot, new Object[0]).equals(displayName))) {
+						// We found the correct method
+						return method;
+					}
+				} catch (final IllegalAccessException ex) {
+					// Log this exception, but ignore it
+					Analysis.LOG.info("An error occured while calling a method.", ex);
+				} catch (final IllegalArgumentException ex) {
+					// Log this exception, but ignore it
+					Analysis.LOG.info("An error occured while calling a method.", ex);
+				} catch (final InvocationTargetException ex) {
+					// Log this exception, but ignore it
+					Analysis.LOG.info("An error occured while calling a method.", ex);
+				}
+			}
+			return null;
+		}
+
+		/**
+		 * Delivers the display object for the given view and the given display.
+		 * 
+		 * @param viewName
+		 *            The name of the view.
+		 * @param displayName
+		 *            The name of the display in the view.
+		 * @return The object for the given display if it exists, null otherwise.
+		 */
+		public Object getDisplay(final String viewName, final String displayName) {
+			return this.displayObjects.get(viewName).get(displayName);
+		}
+
+		@Override
+		public void run() {
+			// Run until we have been interrupted
+			while (!this.terminated) {
+				for (final MIView view : Analysis.this.modelProject.getViews()) {
+					this.displayObjects.get(view.getName());
+					for (final MIDisplayConnector displayConnector : view.getDisplayConnectors()) {
+						// final Object displayObject = viewMap.get(displayConnector.getName());
+						// final Object pluginObject = this.pluginMap.get(displayConnector.getDisplay().getParent());
+						// Update the display object
+						// try {
+						// this.methodMap.get(displayObject).invoke(pluginObject, displayObject);
+						// } catch (final IllegalAccessException ex) {
+						// Analysis.LOG.error("An error occured while updating the display.", ex);
+						// } catch (final IllegalArgumentException ex) {
+						// Analysis.LOG.error("An error occured while updating the display.", ex);
+						// } catch (final InvocationTargetException ex) {
+						// Analysis.LOG.error("An error occured while updating the display.", ex);
+						// } catch (final NullPointerException ex) { // NOPMD
+						// Analysis.LOG.error("An error occured while updating the display.", ex);
+						// }
+					}
+				}
+
+				// Wait a little bit.
+				try {
+					Thread.sleep(UpdateDisplaysThread.SLEEP_TIME_MS);
+				} catch (final InterruptedException ex) {
+					// We have been interrupted. Exit the thread
+					return;
+				}
+			}
+
+		}
+
+		public void terminate() {
+			this.terminated = true;
+		}
+	}
+}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/ClassAndMethodContainer.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ClassAndMethodContainer.java
index ce18dee4..209d63b2 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/ClassAndMethodContainer.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ClassAndMethodContainer.java
@@ -20,9 +20,18 @@
 package kieker.webgui.common;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
+import kieker.analysis.AnalysisController;
+import kieker.analysis.AnalysisController.AnalysisControllerWithMapping;
+import kieker.analysis.AnalysisControllerThread;
+import kieker.analysis.display.HtmlText;
+import kieker.analysis.display.Image;
+import kieker.analysis.display.PlainText;
 import kieker.analysis.display.annotation.Display;
+import kieker.analysis.model.analysisMetaModel.MIProject;
 import kieker.analysis.plugin.AbstractPlugin;
 import kieker.analysis.plugin.annotation.InputPort;
 import kieker.analysis.plugin.annotation.OutputPort;
@@ -57,6 +66,18 @@ public final class ClassAndMethodContainer {
 	 */
 	private static final String MSG_LOAD_EXCEPTION = "An error occured while loading the classes and methods.";
 
+	/**
+	 * This is the class equivalence of {@link AnalysisControllerWithMapping}.
+	 */
+	private Class<?> analysisControllerWithMappingClass;
+	/**
+	 * This is the class equivalence of {@link AnalysisController}.
+	 */
+	private final Class<?> analysisControllerClass;
+	/**
+	 * This is the class equivalence of {@link AnalysisControllerThread}.
+	 */
+	private final Class<?> analysisControllerThreadClass;
 	/**
 	 * This is the class equivalence of {@link AbstractRepository}.
 	 */
@@ -101,6 +122,18 @@ public final class ClassAndMethodContainer {
 	 * This is the class equivalence of {@link Display}.
 	 */
 	private final Class<? extends Annotation> displayAnnotationClass;
+	/**
+	 * This is the class equivalence of {@link Image}.
+	 */
+	private final Class<?> imageClass;
+	/**
+	 * This is the class equivalence of {@link PlainText}.
+	 */
+	private final Class<?> plainTextClass;
+	/**
+	 * This is the class equivalence of {@link HtmlText}.
+	 */
+	private final Class<?> htmlTextClass;
 	/**
 	 * This is the description()-method of the class equivalence of {@link Plugin}.
 	 */
@@ -149,6 +182,42 @@ public final class ClassAndMethodContainer {
 	 * This is the defaultValue()-method of the class equivalence of {@link Property}.
 	 */
 	private final Method propertyDefaultValueMethod;
+	/**
+	 * This is the getText()-method of the class equivalence of {@link PlainText}.
+	 */
+	private final Method plainTextgetTextMethod;
+	/**
+	 * This is the getController()-method of the class equivalence of {@link AnalysisControllerWithMapping}.
+	 */
+	private final Method analysisControllerWithMappingGetController;
+	/**
+	 * This is the getPluginMap()-method of the class equivalence of {@link AnalysisControllerWithMapping}.
+	 */
+	private final Method analysisControllerWithMappingGetMapping;
+	/**
+	 * This is the createAnalysisController(MIProject, ClassLoader)-method of the class equivalence of {@link AnalysisControllerWithMapping}.
+	 */
+	private final Method analysisControllerCreateAnalysisController;
+	/**
+	 * This is the start()-method of the class equivalence of {@link AnalysisController}.
+	 */
+	private final Method analysisControllerThreadStart;
+	/**
+	 * This is the terminate()-method of the class equivalence of {@link AnalysisController}.
+	 */
+	private final Method analysisControllerThreadTerminate;
+	/**
+	 * This is the join(long)-method of the class equivalence of {@link AnalysisController}.
+	 */
+	private final Method analysisControllerThreadJoin;
+	/**
+	 * This is the getState()-method of the class equivalence of {@link AnalysisController}.
+	 */
+	private Method analysisControllerGetState;
+	/**
+	 * This is the constructor for {@link AnalysisControllerThread}, which gets an instance of {@link AnalysisController}.
+	 */
+	private final Constructor<?> analysisControllerThreadConstructor;
 
 	/**
 	 * Creates a new instance of this class, using the given class loader.
@@ -161,18 +230,25 @@ public final class ClassAndMethodContainer {
 	@SuppressWarnings("unchecked")
 	public ClassAndMethodContainer(final ClassLoader classLoader) throws ProjectLoadException {
 		try {
-			this.abstractFilterPluginClass = classLoader.loadClass(AbstractFilterPlugin.class.getCanonicalName());
-			this.abstractReaderPluginClass = classLoader.loadClass(AbstractReaderPlugin.class.getCanonicalName());
-			this.abstractRepositoryClass = classLoader.loadClass(AbstractRepository.class.getCanonicalName());
-			this.abstractPluginClass = classLoader.loadClass(AbstractPlugin.class.getCanonicalName());
-
-			this.pluginAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Plugin.class.getCanonicalName());
-			this.repositoryAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Repository.class.getCanonicalName());
-			this.propertyAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Property.class.getCanonicalName());
-			this.outputPortAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(OutputPort.class.getCanonicalName());
-			this.inputPortAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(InputPort.class.getCanonicalName());
-			this.repositoryPortAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(RepositoryPort.class.getCanonicalName());
-			this.displayAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Display.class.getCanonicalName());
+			this.analysisControllerWithMappingClass = classLoader.loadClass(AnalysisControllerWithMapping.class.getName());
+
+			this.analysisControllerClass = classLoader.loadClass(AnalysisController.class.getName());
+			this.analysisControllerThreadClass = classLoader.loadClass(AnalysisControllerThread.class.getName());
+			this.abstractFilterPluginClass = classLoader.loadClass(AbstractFilterPlugin.class.getName());
+			this.abstractReaderPluginClass = classLoader.loadClass(AbstractReaderPlugin.class.getName());
+			this.abstractRepositoryClass = classLoader.loadClass(AbstractRepository.class.getName());
+			this.abstractPluginClass = classLoader.loadClass(AbstractPlugin.class.getName());
+			this.htmlTextClass = classLoader.loadClass(HtmlText.class.getName());
+			this.plainTextClass = classLoader.loadClass(PlainText.class.getName());
+			this.imageClass = classLoader.loadClass(Image.class.getName());
+
+			this.pluginAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Plugin.class.getName());
+			this.repositoryAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Repository.class.getName());
+			this.propertyAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Property.class.getName());
+			this.outputPortAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(OutputPort.class.getName());
+			this.inputPortAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(InputPort.class.getName());
+			this.repositoryPortAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(RepositoryPort.class.getName());
+			this.displayAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Display.class.getName());
 
 			this.pluginDescriptionMethod = this.pluginAnnotationClass.getMethod("description", new Class<?>[0]);
 			this.repositoryDescriptionMethod = this.repositoryAnnotationClass.getMethod("description", new Class<?>[0]);
@@ -186,6 +262,29 @@ public final class ClassAndMethodContainer {
 			this.repositoryPortNameMethod = this.repositoryPortAnnotationClass.getMethod("name", new Class<?>[0]);
 			this.propertyNameMethod = this.propertyAnnotationClass.getMethod("name", new Class<?>[0]);
 			this.propertyDefaultValueMethod = this.propertyAnnotationClass.getMethod("defaultValue", new Class<?>[0]);
+			this.plainTextgetTextMethod = this.plainTextClass.getMethod("getText", new Class<?>[0]);
+			this.analysisControllerWithMappingGetController = this.analysisControllerWithMappingClass.getMethod("getController", new Class<?>[0]);
+			this.analysisControllerWithMappingGetMapping = this.analysisControllerWithMappingClass.getMethod("getPluginMap", new Class<?>[0]);
+			this.analysisControllerThreadStart = this.analysisControllerThreadClass.getMethod("start", new Class<?>[0]);
+			this.analysisControllerThreadTerminate = this.analysisControllerThreadClass.getMethod("terminate", new Class<?>[0]);
+			this.analysisControllerGetState = this.analysisControllerClass.getMethod("getState", new Class<?>[0]);
+
+			// This is a special case as we need to load some additional classes to search for the correct method
+			final Class<?> miProjectClass = classLoader.loadClass(MIProject.class.getName());
+			final Class<?> classLoaderClass = classLoader.loadClass(ClassLoader.class.getName());
+			this.analysisControllerCreateAnalysisController = this.analysisControllerClass.getMethod("createAnalysisController", miProjectClass, classLoaderClass);
+
+			// Another special case as the parameter is a long
+			final Method[] methods = this.analysisControllerThreadClass.getMethods();
+			Method joinMethod = null;
+			for (final Method method : methods) {
+				if ("join".equals(method.getName())) {
+					joinMethod = method;
+				}
+			}
+			this.analysisControllerThreadJoin = joinMethod;
+
+			this.analysisControllerThreadConstructor = this.analysisControllerThreadClass.getConstructor(this.analysisControllerClass);
 		} catch (final ClassNotFoundException ex) {
 			ClassAndMethodContainer.LOG.error(ClassAndMethodContainer.MSG_LOAD_EXCEPTION, ex);
 			throw new ProjectLoadException(ClassAndMethodContainer.MSG_LOAD_EXCEPTION, ex);
@@ -408,4 +507,232 @@ public final class ClassAndMethodContainer {
 		return this.propertyDefaultValueMethod;
 	}
 
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#imageClass}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Class<?> getImageClass() {
+		return this.imageClass;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#plainTextClass}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Class<?> getPlainTextClass() {
+		return this.plainTextClass;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#htmlTextClass}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Class<?> getHtmlTextClass() {
+		return this.htmlTextClass;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#plainTextgetTextMethod}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Method getPlainTextgetTextMethod() {
+		return this.plainTextgetTextMethod;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#analysisControllerWithMappingGetMapping}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Method getAnalysisControllerWithMappingGetMapping() {
+		return this.analysisControllerWithMappingGetMapping;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#analysisControllerClass}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Class<?> getAnalysisControllerClass() {
+		return this.analysisControllerClass;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#analysisControllerWithMappingClass}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Class<?> getAnalysisControllerWithMappingClass() {
+		return this.analysisControllerWithMappingClass;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#analysisControllerThreadClass}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Class<?> getAnalysisControllerThreadClass() {
+		return this.analysisControllerThreadClass;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#analysisControllerCreateAnalysisController}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Method getAnalysisControllerCreateAnalysisController() {
+		return this.analysisControllerCreateAnalysisController;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#analysisControllerWithMappingGetController}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Method getAnalysisControllerWithMappingGetController() {
+		return this.analysisControllerWithMappingGetController;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#analysisControllerThreadStart}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Method getAnalysisControllerThreadStart() {
+		return this.analysisControllerThreadStart;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#analysisControllerThreadTerminate}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Method getAnalysisControllerThreadTerminate() {
+		return this.analysisControllerThreadTerminate;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#analysisControllerThreadJoin}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Method getAnalysisControllerThreadJoin() {
+		return this.analysisControllerThreadJoin;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#analysisControllerThreadJoin}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Method getAnalysisControllerGetState() {
+		return this.analysisControllerGetState;
+	}
+
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#analysisControllerThreadConstructor}.
+	 * 
+	 * @return The current value for the field.
+	 */
+
+	public Constructor<?> getAnalysisControllerThreadConstructor() {
+		return this.analysisControllerThreadConstructor;
+	}
+
+	/**
+	 * This method can be used to invoke a given method with given parameters, without having to mind about the exceptions. If an exception occurs, the given default
+	 * value will be returned.
+	 * 
+	 * @param method
+	 *            The method to be invoked.
+	 * @param obj
+	 *            The object on which the method will be invoked.
+	 * @param defaultReturn
+	 *            The default return value in case of an exception.
+	 * @param values
+	 *            The parameters for the method.
+	 * @return The result of the invoked method if everything went well, the default value otherwise.
+	 */
+	public static Object invokeMethod(final Method method, final Object obj, final Object defaultReturn, final Object... values) {
+		try {
+			return method.invoke(obj, values);
+		} catch (final IllegalAccessException ex) {
+			ClassAndMethodContainer.LOG.error("An error occured during a reflection method call.", ex);
+			return defaultReturn;
+		} catch (final IllegalArgumentException ex) {
+			ClassAndMethodContainer.LOG.error("An error occured during a reflection method call.", ex);
+			return defaultReturn;
+		} catch (final InvocationTargetException ex) {
+			ClassAndMethodContainer.LOG.error("An error occured during a reflection method call.", ex);
+			return defaultReturn;
+		}
+	}
+
+	/**
+	 * This method can be used to invoke a given constructor with given parameters, without having to mind about the exceptions. If an exception occurs, null will be
+	 * returned.
+	 * 
+	 * @param constructor
+	 *            The constructor to be invoked.
+	 * @param values
+	 *            The parameters for the method.
+	 * @return The result of the invoked method if everything went well, null otherwise.
+	 */
+	public static Object invokeConstructor(final Constructor<?> constructor, final Object... values) {
+		try {
+			return constructor.newInstance(values);
+		} catch (final InstantiationException ex) {
+			ClassAndMethodContainer.LOG.error("An error occured during a reflection constructor call.", ex);
+			return null;
+		} catch (final IllegalAccessException ex) {
+			ClassAndMethodContainer.LOG.error("An error occured during a reflection constructor call.", ex);
+			return null;
+		} catch (final IllegalArgumentException ex) {
+			ClassAndMethodContainer.LOG.error("An error occured during a reflection constructor call.", ex);
+			return null;
+		} catch (final InvocationTargetException ex) {
+			ClassAndMethodContainer.LOG.error("An error occured during a reflection constructor call.", ex);
+			return null;
+		}
+
+	}
+
+	/**
+	 * This method can be used to invoke a given method with no parameters, without having to mind about the exceptions. If an exception occurs, the given default
+	 * value will be returned. A call to this method is the same as {@link ClassAndMethodContainer#invokeMethod(Method, Object, Object, Object...)} with
+	 * {@code new Object[0]} as parameters.
+	 * 
+	 * @param method
+	 *            The method to be invoked.
+	 * @param obj
+	 *            The object on which the method will be invoked.
+	 * @param defaultReturn
+	 *            The default return value in case of an exception.
+	 * @return The result of the invoked method if everything went well, the default value otherwise.
+	 */
+	public static Object invokeMethod(final Method method, final Object obj, final Object defaultReturn) {
+		return ClassAndMethodContainer.invokeMethod(method, obj, defaultReturn, new Object[0]);
+	}
+
+	/**
+	 * This method can be used to invoke a given <b>class</b>-method with no parameters, without having to mind about the exceptions. If an exception occurs, the
+	 * given default value will be returned. A call to this method is the same as {@link ClassAndMethodContainer#invokeMethod(Method, Object, Object, Object...)}
+	 * with null as object.
+	 * 
+	 * @param method
+	 *            The method to be invoked.
+	 * @param defaultReturn
+	 *            The default return value in case of an exception.
+	 * @param values
+	 *            The parameters for the method.
+	 * @return The result of the invoked method if everything went well, the default value otherwise.
+	 */
+	public static Object invokeClassMethod(final Method method, final Object defaultReturn, final Object... values) {
+		return ClassAndMethodContainer.invokeMethod(method, null, defaultReturn, values);
+	}
+
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/Triple.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/Triple.java
deleted file mode 100644
index af5a7fbd..00000000
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/Triple.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/***************************************************************************
- * Copyright 2012 by
- *  + Christian-Albrechts-University of Kiel
- *    + Department of Computer Science
- *      + Software Engineering Group 
- *  and others.
- *
- * 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.common;
-
-/**
- * This is a simple helper class which can store three values.
- * 
- * @author Nils Christian Ehmke
- * @version 1.0
- * 
- * @param <F>
- *            The type of the first element.
- * @param <S>
- *            The type of the second element.
- * @param <T>
- *            The type of the third element.
- */
-public class Triple<F, S, T> {
-	/**
-	 * This is the first element.
-	 */
-	private F fst;
-	/**
-	 * This is the second element.
-	 */
-	private S snd;
-	/**
-	 * This is the third element.
-	 */
-	private T thd;
-
-	/**
-	 * Creates a new instance of this class with null values stored for the elements.
-	 */
-	public Triple() {
-		// No code necessary
-	}
-
-	/**
-	 * Creates a new instance of this class using the given values.
-	 * 
-	 * @param fst
-	 *            The first element to be stored in this object.
-	 * @param snd
-	 *            The second element to be stored in this object.
-	 * @param thd
-	 *            The third element to be stored in this object.
-	 */
-	public Triple(final F fst, final S snd, final T thd) {
-		this.fst = fst;
-		this.snd = snd;
-		this.thd = thd;
-	}
-
-	/**
-	 * Delivers the first element.
-	 * 
-	 * @return The first element.
-	 */
-	public F getFst() {
-		return this.fst;
-	}
-
-	/**
-	 * Sets the first element to a new value.
-	 * 
-	 * @param fst
-	 *            The new first element.
-	 */
-	public void setFst(final F fst) {
-		this.fst = fst;
-	}
-
-	/**
-	 * Delivers the second element.
-	 * 
-	 * @return The second element.
-	 */
-	public S getSnd() {
-		return this.snd;
-	}
-
-	/**
-	 * Sets the second element to a new value.
-	 * 
-	 * @param snd
-	 *            The new second element.
-	 */
-	public void setSnd(final S snd) {
-		this.snd = snd;
-	}
-
-	/**
-	 * Delivers the third element.
-	 * 
-	 * @return The third element.
-	 */
-	public T getThd() {
-		return this.thd;
-	}
-
-	/**
-	 * Sets the third element to a new value.
-	 * 
-	 * @param thd
-	 *            The new third element.
-	 */
-	public void setThd(final T thd) {
-		this.thd = thd;
-	}
-
-}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisAlreadyInstantiatedException.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisAlreadyInstantiatedException.java
new file mode 100644
index 00000000..e86ef258
--- /dev/null
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisAlreadyInstantiatedException.java
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * Copyright 2012 by
+ *  + Christian-Albrechts-University of Kiel
+ *    + Department of Computer Science
+ *      + Software Engineering Group 
+ *  and others.
+ *
+ * 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.common.exception;
+
+/**
+ * This exception shows that the analysis has not yet been instantiated.
+ * 
+ * @author Nils Christian Ehmke
+ * @version 1.0
+ */
+public class AnalysisAlreadyInstantiatedException extends Exception {
+	/**
+	 * The serial version UID.
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Creates a new instance of this class.
+	 */
+	public AnalysisAlreadyInstantiatedException() {
+		// No code necessary
+	}
+
+	/**
+	 * Creates a new instance of this class using the given parameters.
+	 * 
+	 * @param msg
+	 *            The message used for the exception.
+	 */
+	public AnalysisAlreadyInstantiatedException(final String msg) {
+		super(msg);
+	}
+}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisAlreadyStartedException.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisAlreadyStartedException.java
new file mode 100644
index 00000000..8076da12
--- /dev/null
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisAlreadyStartedException.java
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * Copyright 2012 by
+ *  + Christian-Albrechts-University of Kiel
+ *    + Department of Computer Science
+ *      + Software Engineering Group 
+ *  and others.
+ *
+ * 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.common.exception;
+
+/**
+ * This exception shows that the given project has already been started.
+ * 
+ * @author Nils Christian Ehmke
+ * @version 1.0
+ */
+public class AnalysisAlreadyStartedException extends Exception {
+	/**
+	 * The serial version UID.
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Creates a new instance of this class.
+	 */
+	public AnalysisAlreadyStartedException() {
+		// No code necessary
+	}
+
+	/**
+	 * Creates a new instance of this class using the given parameters.
+	 * 
+	 * @param msg
+	 *            The message used for the exception.
+	 */
+	public AnalysisAlreadyStartedException(final String msg) {
+		super(msg);
+	}
+
+	public AnalysisAlreadyStartedException(final String msg, final Throwable ex) {
+		super(msg, ex);
+	}
+}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisInstantiationException.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisInstantiationException.java
new file mode 100644
index 00000000..e0495a85
--- /dev/null
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisInstantiationException.java
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * Copyright 2012 by
+ *  + Christian-Albrechts-University of Kiel
+ *    + Department of Computer Science
+ *      + Software Engineering Group 
+ *  and others.
+ *
+ * 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.common.exception;
+
+public class AnalysisInstantiationException extends Exception {
+	/**
+	 * The serial version UID.
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Creates a new instance of this class.
+	 */
+	public AnalysisInstantiationException() {
+		// No code necessary
+	}
+
+	/**
+	 * Creates a new instance of this class using the given parameters.
+	 * 
+	 * @param msg
+	 *            The message used for the exception.
+	 */
+	public AnalysisInstantiationException(final String msg) {
+		super(msg);
+	}
+
+	/**
+	 * Creates a new instance of this class using the given parameters.
+	 * 
+	 * @param msg
+	 *            The message used for the exception.
+	 * @param The
+	 *            cause for the method.
+	 */
+	public AnalysisInstantiationException(final String msg, final Throwable cause) {
+		super(msg, cause);
+	}
+}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotRunningException.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotStartedException.java
similarity index 89%
rename from Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotRunningException.java
rename to Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotStartedException.java
index 78c162ad..419d00c8 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotRunningException.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotStartedException.java
@@ -26,7 +26,7 @@ package kieker.webgui.common.exception;
  * @author Nils Christian Ehmke
  * @version 1.0
  */
-public class AnalysisNotRunningException extends Exception {
+public class AnalysisNotStartedException extends Exception {
 	/**
 	 * The serial version UID.
 	 */
@@ -35,7 +35,7 @@ public class AnalysisNotRunningException extends Exception {
 	/**
 	 * Creates a new instance of this class.
 	 */
-	public AnalysisNotRunningException() {
+	public AnalysisNotStartedException() {
 		// No code necessary
 	}
 
@@ -45,7 +45,7 @@ public class AnalysisNotRunningException extends Exception {
 	 * @param msg
 	 *            The message used for the exception.
 	 */
-	public AnalysisNotRunningException(final String msg) {
+	public AnalysisNotStartedException(final String msg) {
 		super(msg);
 	}
 }
-- 
GitLab