From 3ef234a48cff0dd52c12f60b4eee1f4cb0b27e7e Mon Sep 17 00:00:00 2001
From: Nils Christian Ehmke <nie@informatik.uni-kiel.de>
Date: Mon, 10 Sep 2012 15:44:43 +0200
Subject: [PATCH] Updated the FlowEditor; Removed some bugs; A lot of
 refactoring

---
 .../beans/application/ProjectsBean.java       |   6 +-
 .../beans/view/CurrentAnalysisEditorBean.java | 644 ++++++++----------
 .../view/CurrentAnalysisEditorGraphBean.java  |  72 +-
 .../beans/view/CurrentCockpitEditorBean.java  |  20 +-
 .../beans/view/CurrentControllerBean.java     |  14 +-
 .../java/kieker/webgui/common/ACManager.java  |   8 +-
 .../java/kieker/webgui/common/Analysis.java   | 134 ++--
 .../common/ClassAndMethodContainer.java       |  20 +-
 .../java/kieker/webgui/common/FSManager.java  |   6 +
 .../kieker/webgui/common/PluginFinder.java    |  18 +-
 .../src/main/webapp/js/flowEditor.js          |  43 +-
 Kieker.WebGUI/src/main/webapp/js/jit.js       |   4 +-
 12 files changed, 486 insertions(+), 503 deletions(-)

diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java
index 5640055a..fafdd177 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java
@@ -40,6 +40,7 @@ import kieker.webgui.beans.view.CurrentProjectOverviewBean;
 import kieker.webgui.common.ACManager;
 import kieker.webgui.common.FSManager;
 import kieker.webgui.common.exception.ProjectAlreadyExistingException;
+import kieker.webgui.common.exception.ProjectLoadException;
 
 /**
  * The {@link ProjectsBean} is a JSF managed bean to manage a list with all application wide available projects. It provides methods to receive this list as well as
@@ -150,13 +151,12 @@ public final class ProjectsBean {
 	 *            The name of the project to be opened.
 	 * @return Either the model instance if the loading was successful or null otherwise. In the latter case, the user will be informed via the growl-component.
 	 */
-	public MIProject openProject(final String project) {
+	public MIProject openProject(final String project) throws ProjectLoadException {
 		try {
 			return FSManager.getInstance().openProject(project);
 		} catch (final IOException ex) {
 			ProjectsBean.LOG.error("An error occured while loading the project.", ex);
-			ProjectsBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project.");
-			return null;
+			throw new ProjectLoadException("An error occured while loading the project.", ex);
 		}
 	}
 
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorBean.java
index dc089c4c..d25d44a7 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorBean.java
@@ -22,12 +22,12 @@ package kieker.webgui.beans.view;
 
 import java.io.IOException;
 import java.lang.annotation.Annotation;
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
@@ -53,6 +53,8 @@ import kieker.analysis.model.analysisMetaModel.MIRepositoryConnector;
 import kieker.analysis.model.analysisMetaModel.impl.MAnalysisMetaModelFactory;
 import kieker.analysis.plugin.AbstractPlugin;
 import kieker.analysis.plugin.annotation.Property;
+import kieker.analysis.plugin.filter.AbstractFilterPlugin;
+import kieker.analysis.plugin.reader.AbstractReaderPlugin;
 import kieker.analysis.repository.AbstractRepository;
 import kieker.common.logging.Log;
 import kieker.common.logging.LogFactory;
@@ -74,9 +76,13 @@ import org.eclipse.emf.ecore.EObject;
 
 /**
  * The {@link CurrentAnalysisEditorBean} contains the necessary data behind an instance of the analysis editor. It provides various methods to manipulate the current
- * project, as the analysis editor is the most important part of the whole application.<br>
+ * project, as the analysis editor is the most important part of the whole application. The connection to the graph within the editor is done via another bean (the
+ * {@link CurrentAnalysisEditorGraphBean}).<br>
  * The class is a JSF managed bean with view scope to make sure that one user (even in one session) can open multiple projects at a time without causing any
- * problems.
+ * problems.<br>
+ * If editing this class as a programmer keep in mind that the class makes excessive use of java reflection (via {@link ClassAndMethodContainer}) to use the correct
+ * classes within every project. It doesn't really use the classes loaded by the WebGUI-ClassLoader. This results also in some methods which returns elements from
+ * the type {@link Object} instead of more specific types to avoid incompatibilities between the multiple loaded classes.
  * 
  * @author Nils Christian Ehmke
  * @version 1.0
@@ -85,49 +91,66 @@ import org.eclipse.emf.ecore.EObject;
 @ViewScoped
 public final class CurrentAnalysisEditorBean {
 	/**
-	 * This is the log for errors, exceptions etc.
+	 * This field contains the log-object for the whole class, which will be used to log all important errors and exceptions which occur.
 	 */
 	private static final Log LOG = LogFactory.getLog(CurrentAnalysisEditorBean.class);
 	/**
-	 * This is the factory which will be used to create new components for the project.
+	 * This field contains the factory, which will be used to create the new components for the project.
 	 */
 	private final MIAnalysisMetaModelFactory factory = new MAnalysisMetaModelFactory();
 	/**
-	 * This is the actual model instance. It is the in-memory-model of the current (session) user.
+	 * This field contains the actual model instance, representing the in-memory model of the current view.
 	 */
 	private MIProject project;
 	/**
-	 * This is the corresponding class loader to the project. It contains always the libraries within the lib-folder of the project.
+	 * This is the corresponding class loader to the project. It contains always the libraries within the lib-folder of the project and additionaly the kieker
+	 * library by default.
 	 */
 	private ClassLoader classLoader;
 	/**
-	 * This is the corresponding class loader to the project. It contains always the correct class loader.
+	 * This is the plugin finder for the current project. It contains always a reference to the correct {@link CurrentAnalysisEditorBean#classLoader} to be able to
+	 * locate the available plugins and repositories.
 	 */
 	private PluginFinder pluginFinder;
+	/**
+	 * This component contains the classes and methods loaded with the specific project class loader.
+	 */
+	private ClassAndMethodContainer classAndMethodContainer;
 	/**
 	 * This is the name of the stored project. It can be used as an identifier within the FS-Manager
 	 */
 	private String projectName;
 	/**
-	 * This is the time stamp of the moment, the project was loaded or last saved. It can be used to check whether the project has been modified in the meanwhile.
+	 * This is the time stamp of the moment, the project was loaded or last saved. It can be used to check whether the project has been modified externally in the
+	 * meanwhile.
 	 */
 	private long timeStamp;
 	/**
-	 * This list contains the available repositories for the current project.
+	 * This flag determines whether the project has been modified internally and can be used to warn the user about unsaved changes.
+	 */
+	private boolean modified;
+	/**
+	 * This list contains the available repositories for the current project. Keep in mind: The list doesn't really contain classes from the type
+	 * {@code AbstractRepository}, as the repositories are loaded with the specific project class loader. This is just possible as the generic-classes work
+	 * internally with {@code Object}.
 	 */
-	private final List<Class<?>> availableRepositories = Collections.synchronizedList(new ArrayList<Class<?>>());
+	private final List<Class<AbstractRepository>> availableRepositories = Collections.synchronizedList(new ArrayList<Class<AbstractRepository>>());
 	/**
-	 * This list contains the available filters for the current project.
+	 * This list contains the available filters for the current project. Keep in mind: The list doesn't really contain classes from the type
+	 * {@code AbstractFilterPlugin}, as the repositories are loaded with the specific project class loader. This is just possible as the generic-classes work
+	 * internally with {@code Object}.
 	 */
-	private final List<Class<?>> availableFilters = Collections.synchronizedList(new ArrayList<Class<?>>());
+	private final List<Class<AbstractFilterPlugin>> availableFilters = Collections.synchronizedList(new ArrayList<Class<AbstractFilterPlugin>>());
 	/**
-	 * This list contains the available readers for the current project.
+	 * This list contains the available readers for the current project. Keep in mind: The list doesn't really contain classes from the type
+	 * {@code AbstractReaderPlugin}, as the repositories are loaded with the specific project class loader. This is just possible as the generic-classes work
+	 * internally with {@code Object}.
 	 */
-	private final List<Class<?>> availableReaders = Collections.synchronizedList(new ArrayList<Class<?>>());
+	private final List<Class<AbstractReaderPlugin>> availableReaders = Collections.synchronizedList(new ArrayList<Class<AbstractReaderPlugin>>());
 	/**
-	 * This field contains the currently selected node (this can either be a plugin or a repository).
+	 * This field contains the currently selected component (this can either be a plugin ({@link MIPlugin}) or a repository ({@link MIRepository})).
 	 */
-	private EObject selectedNode;
+	private EObject selectedComponent;
 
 	@ManagedProperty(value = "#{projectsBean}")
 	private ProjectsBean projectsBean;
@@ -135,10 +158,8 @@ public final class CurrentAnalysisEditorBean {
 	@ManagedProperty(value = "#{currentAnalysisEditorGraphBean}")
 	private CurrentAnalysisEditorGraphBean currentAnalysisEditorGraphBean;
 
-	private ClassAndMethodContainer classAndMethodContainer;
-
 	/**
-	 * Creates a new instance of this class.
+	 * Creates a new instance of this class. <b>Do not call this constructor manually. It will only be accessed by JSF.</b>
 	 */
 	public CurrentAnalysisEditorBean() {
 		// No code necessary
@@ -209,73 +230,67 @@ public final class CurrentAnalysisEditorBean {
 	/**
 	 * 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 initialize() throws ProjectLoadException {
+	public void initialize() {
 		synchronized (this) {
-			// Make sure that the initialization will only be done for the init request.
-			if (!FacesContext.getCurrentInstance().isPostback()) {
-				this.project = this.projectsBean.openProject(this.projectName);
-
-				if (this.project != null) {
+			try {
+				// Make sure that the initialization will only be done for the init request. During all other requests, the method call have to be ignored.
+				if (!FacesContext.getCurrentInstance().isPostback()) {
+					// Load the project itself
+					this.project = this.projectsBean.openProject(this.projectName);
 					// Remember the current time! This is important for the later comparison of the time stamps.
 					this.resetTimeStamp();
 					// Update the class loader and the specific classes used within various methods in this bean
 					this.reloadClassLoader();
 					this.reloadClassesAndMethods();
 					// Add the libraries within the lib-folder to the current model
-					this.addLibrariesToModel();
+					this.initializeModelLibraries();
 					// Load the available readers, filters and repositories
-					this.loadToolPalette();
+					this.initializeToolPalette();
+					// The project hasn't been modified (yet)
+					this.modified = false;
 				}
+			} catch (final ProjectLoadException ex) {
+				CurrentAnalysisEditorBean.LOG.error("An error occured while loading the project.", ex);
+				CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project.");
 			}
 		}
 	}
 
-	private void reloadClassesAndMethods() throws ProjectLoadException {
-		this.classAndMethodContainer = new ClassAndMethodContainer(this.classLoader);
-	}
-
 	/**
-	 * This method loads the list of available readers, filters and repositories, using the current libraries within the model.
+	 * This method reloads the field containing the methods and classes, using the current class loader.
+	 * 
+	 * @throws ProjectLoadException
+	 *             If one or more of the classes and methods necessary for {@link ClassAndMethodContainer} could not be found using the given class loader.
 	 */
-	private void loadToolPalette() {
-		synchronized (this) {
-			// Clean our tool palette
-			this.availableFilters.clear();
-			this.availableReaders.clear();
-			this.availableRepositories.clear();
-
-			// Make sure there is a project.
-			if (this.project != null) {
-				// Run through all libraries
-				for (final MIDependency lib : this.project.getDependencies()) {
-					this.addToToolPalette(lib);
-				}
-				this.addKiekerToToolPalette();
-			}
-		}
-	}
-
-	private void addKiekerToToolPalette() {
+	private void reloadClassesAndMethods() throws ProjectLoadException {
 		synchronized (this) {
-			this.addToToolPalette(FSManager.getInstance().getKiekerURL());
+			this.classAndMethodContainer = new ClassAndMethodContainer(this.classLoader);
 		}
 	}
 
 	/**
-	 * This method adds all available readers, filters and repositories within the given library to the lists of this bean.
+	 * This method loads the list of available readers, filters and repositories, using the current libraries within the model.
 	 * 
-	 * @param lib
-	 *            The library used to load the plugins and repositories.
+	 * @throws ProjectLoadException
 	 */
-	private void addToToolPalette(final MIDependency lib) {
+	private void initializeToolPalette() throws ProjectLoadException {
 		synchronized (this) {
 			try {
-				this.addToToolPalette(FSManager.getInstance().getURL(lib, this.projectName));
+				// Clean our tool palette
+				this.availableFilters.clear();
+				this.availableReaders.clear();
+				this.availableRepositories.clear();
+
+				// Run through all libraries and add their content to our lists
+				for (final MIDependency lib : this.project.getDependencies()) {
+					this.addContentsToToolPalette(FSManager.getInstance().getURL(lib, this.projectName));
+				}
+				// Run also through the kieker library
+				this.addContentsToToolPalette(FSManager.getInstance().getKiekerURL());
 			} catch (final MalformedURLException ex) {
-				ex.printStackTrace();
+				CurrentAnalysisEditorBean.LOG.error("A library could not be loaded correctly.", ex);
+				throw new ProjectLoadException("A library could not be loaded correctly.", ex);
 			}
 		}
 	}
@@ -286,33 +301,40 @@ public final class CurrentAnalysisEditorBean {
 	 * @param url
 	 *            The library url used to load the plugins and repositories.
 	 */
-	private void addToToolPalette(final URL url) {
-		final List<Class<?>> repositories = this.pluginFinder.getAllRepositoriesWithinJar(url);
-		final List<Class<?>> plugins = this.pluginFinder.getAllPluginsWithinJar(url);
-		// Now run through the available classes and add all non-abstract classes to our lists
-		for (final Class<?> repository : repositories) {
-			if (!Modifier.isAbstract(repository.getModifiers())) {
-				this.availableRepositories.add(repository);
+	@SuppressWarnings("unchecked")
+	private void addContentsToToolPalette(final URL url) {
+		synchronized (this) {
+			// Get all repositories and plugins within the given library
+			final List<Class<AbstractRepository>> repositories = this.pluginFinder.getAllRepositoriesWithinJar(url);
+			final List<Class<AbstractPlugin>> plugins = this.pluginFinder.getAllPluginsWithinJar(url);
+
+			// Now run through the available classes and add all non-abstract classes to our lists
+			for (final Class<AbstractRepository> repository : repositories) {
+				if (!Modifier.isAbstract(repository.getModifiers())) {
+					this.availableRepositories.add(repository);
+				}
 			}
-		}
-		for (final Class<?> plugin : plugins) {
-			if (!Modifier.isAbstract(plugin.getModifiers())) {
-				// The following cast results in the unchecked-cast-warnings, but we know that the cast should be correct.
-				if (this.classAndMethodContainer.getAbstractFilterPluginClass().isAssignableFrom(plugin)) {
-					this.availableFilters.add(plugin);
-				} else {
-					if (this.classAndMethodContainer.getAbstractReaderPluginClass().isAssignableFrom(plugin)) {
-						this.availableReaders.add(plugin);
+
+			for (final Class<?> plugin : plugins) {
+				if (!Modifier.isAbstract(plugin.getModifiers())) {
+					// The following cast results in the unchecked-cast-warnings, but we know that the cast should be correct.
+					if (this.classAndMethodContainer.getAbstractFilterPluginClass().isAssignableFrom(plugin)) {
+						this.availableFilters.add((Class<AbstractFilterPlugin>) plugin);
+					} else {
+						if (this.classAndMethodContainer.getAbstractReaderPluginClass().isAssignableFrom(plugin)) {
+							this.availableReaders.add((Class<AbstractReaderPlugin>) plugin);
+						}
 					}
 				}
 			}
+
 		}
 	}
 
 	/**
 	 * This method takes all libraries from the lib-folder and adds them to the in-memory-model.
 	 */
-	private void addLibrariesToModel() {
+	private void initializeModelLibraries() {
 		synchronized (this) {
 			final List<MIDependency> libs = FSManager.getInstance().getModelLibraries(this.projectName);
 			// Add them, but remove all existing dependencies so far to avoid double entries. This also makes sure that the model - after it has been opened - points
@@ -327,6 +349,7 @@ public final class CurrentAnalysisEditorBean {
 	 * project.
 	 * 
 	 * @throws ProjectLoadException
+	 *             If something went wrong.
 	 */
 	private void reloadClassLoader() throws ProjectLoadException {
 		synchronized (this) {
@@ -334,11 +357,9 @@ public final class CurrentAnalysisEditorBean {
 			try {
 				this.pluginFinder = new PluginFinder(this.classLoader);
 			} catch (final ClassNotFoundException ex) {
-				CurrentAnalysisEditorBean.LOG.error("Could not load classes.", ex);
-				throw new ProjectLoadException();
+				throw new ProjectLoadException("Could not load classes.", ex);
 			} catch (final NullPointerException ex) {
-				CurrentAnalysisEditorBean.LOG.error("Invalid class loader", ex);
-				throw new ProjectLoadException();
+				throw new ProjectLoadException("Invalid class loader.", ex);
 			}
 		}
 	}
@@ -376,76 +397,62 @@ public final class CurrentAnalysisEditorBean {
 
 	/**
 	 * This method can be used to get the description of an {@link AbstractPlugin}- or an {@link AbstractRepository}-class. The description is read via the
-	 * annotation.
+	 * annotation using the java reflection API.
 	 * 
 	 * @param clazz
 	 *            The class whose description should be extracted.
 	 * @return The description for the class or a substitute if none is available. This is in either case human readable.
 	 */
 	public String getDescription(final Class<?> clazz) {
-		try {
-			// Get the two potential annotations
-			final Annotation annotationPlugin = clazz.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass());
-			final Annotation annotationRepository = clazz.getAnnotation(this.classAndMethodContainer.getRepositoryAnnotationClass());
-
-			// Now check which one of them is available
-			if ((annotationPlugin == null) || ((String) this.classAndMethodContainer.getPluginDescriptionMethod().invoke(annotationPlugin, new Object[0])).isEmpty()) {
-				if ((annotationRepository == null)
-						|| ((String) this.classAndMethodContainer.getRepositoryDescriptionMethod().invoke(annotationRepository, new Object[0])).isEmpty()) {
-					// None. Deliver a human readable substitute.
-					return "No description available";
-				} else {
-					return (String) this.classAndMethodContainer.getRepositoryDescriptionMethod().invoke(annotationRepository, new Object[0]);
-				}
+		// Get the two potential annotations
+		final Annotation annotationPlugin = clazz.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass());
+		final Annotation annotationRepository = clazz.getAnnotation(this.classAndMethodContainer.getRepositoryAnnotationClass());
+
+		final Method pluginDescrMethod = this.classAndMethodContainer.getPluginDescriptionMethod();
+		final Method repoDescrMethod = this.classAndMethodContainer.getRepositoryDescriptionMethod();
+
+		// Now check which one of them is available
+		if ((annotationPlugin == null) || ((String) ClassAndMethodContainer.invokeMethod(pluginDescrMethod, annotationPlugin, "")).isEmpty()) {
+			if ((annotationRepository == null) || ((String) ClassAndMethodContainer.invokeMethod(repoDescrMethod, annotationRepository, "")).isEmpty()) {
+				// None. Deliver a human readable substitute.
+				return "No description available";
 			} else {
-				return (String) this.classAndMethodContainer.getPluginDescriptionMethod().invoke(annotationPlugin, new Object[0]);
+				return (String) ClassAndMethodContainer.invokeMethod(repoDescrMethod, annotationRepository, "No description available");
 			}
-		} catch (final IllegalAccessException ex) {
-			CurrentAnalysisEditorBean.LOG.warn("Could not invoke method", ex);
-			return "No description available";
-		} catch (final IllegalArgumentException ex) {
-			CurrentAnalysisEditorBean.LOG.warn("Could not invoke method", ex);
-			return "No description available";
-		} catch (final InvocationTargetException ex) {
-			CurrentAnalysisEditorBean.LOG.warn("Could not invoke method", ex);
-			return "No description available";
+		} else {
+			return (String) ClassAndMethodContainer.invokeMethod(pluginDescrMethod, annotationPlugin, "No description available");
 		}
 	}
 
+	/**
+	 * Delivers the properties of the given class, using the annotations and the java reflection API.
+	 * 
+	 * @param clazz
+	 *            The class whose properties will be delivered.
+	 * @return A list of properties. It contains instances of {@link Property} - but those from the project class loader.
+	 */
 	public List<Annotation> getProperties(final Class<?> clazz) {
-		final List<Annotation> result = new ArrayList<Annotation>();
+		// Get the two potential annotations
+		final Annotation annotationPlugin = clazz.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass());
+		final Annotation annotationRepository = clazz.getAnnotation(this.classAndMethodContainer.getRepositoryAnnotationClass());
 
-		try {
-			// Get the two potential annotations
-			final Annotation annotationPlugin = clazz.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass());
-			final Annotation annotationRepository = clazz.getAnnotation(this.classAndMethodContainer.getRepositoryAnnotationClass());
+		final Annotation[] properties;
 
-			final Annotation[] properties;
-
-			// Now check which one of them is available
-			if (annotationPlugin == null) {
-				if (annotationRepository == null) {
-					// None.
-					properties = new Property[0];
-				} else {
-					properties = (Annotation[]) this.classAndMethodContainer.getRepositoryConfigurationMethod().invoke(annotationRepository, new Object[0]);
-				}
+		// Now check which one of them is available
+		if (annotationPlugin == null) {
+			if (annotationRepository == null) {
+				// None.
+				properties = new Property[0];
 			} else {
-				properties = (Annotation[]) this.classAndMethodContainer.getPluginConfigurationMethod().invoke(annotationPlugin, new Object[0]);
-			}
-
-			for (final Annotation property : properties) {
-				result.add(property);
+				properties = (Annotation[]) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getRepositoryConfigurationMethod(),
+						annotationRepository, new Property[0]);
 			}
-
-		} catch (final IllegalAccessException ex) {
-			CurrentAnalysisEditorBean.LOG.warn("Could not invoke method", ex);
-		} catch (final IllegalArgumentException ex) {
-			CurrentAnalysisEditorBean.LOG.warn("Could not invoke method", ex);
-		} catch (final InvocationTargetException ex) {
-			CurrentAnalysisEditorBean.LOG.warn("Could not invoke method", ex);
+		} else {
+			properties = (Annotation[]) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPluginConfigurationMethod(),
+					annotationPlugin, new Property[0]);
 		}
-		return result;
+
+		return Arrays.asList(properties);
 	}
 
 	/**
@@ -480,24 +487,17 @@ public final class CurrentAnalysisEditorBean {
 	public List<Annotation> getOutputPorts(final Class<?> clazz) {
 		final List<Annotation> result = new ArrayList<Annotation>();
 
-		try {
-			// Get the potential annotation
-			final Annotation annotationPlugin = clazz.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass());
+		// Get the potential annotation
+		final Annotation annotationPlugin = clazz.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass());
 
-			// Now check whether it is available
-			if (annotationPlugin != null) {
-				for (final Annotation oPort : (Annotation[]) this.classAndMethodContainer.getPluginOutputPortsMethod().invoke(annotationPlugin, new Object[0])) {
-					result.add(oPort);
-				}
+		// Now check whether it is available
+		if (annotationPlugin != null) {
+			for (final Annotation oPort : (Annotation[]) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPluginOutputPortsMethod(),
+					annotationPlugin, new Annotation[0])) {
+				result.add(oPort);
 			}
-
-		} catch (final IllegalAccessException ex) {
-			CurrentAnalysisEditorBean.LOG.warn("Could not invoke method", ex);
-		} catch (final IllegalArgumentException ex) {
-			CurrentAnalysisEditorBean.LOG.warn("Could not invoke method", ex);
-		} catch (final InvocationTargetException ex) {
-			CurrentAnalysisEditorBean.LOG.warn("Could not invoke method", ex);
 		}
+
 		return result;
 	}
 
@@ -510,26 +510,28 @@ public final class CurrentAnalysisEditorBean {
 	 */
 	public List<Annotation> getRepositoryPorts(final Class<?> clazz) {
 		final List<Annotation> result = new ArrayList<Annotation>();
-		try {
-			// Get the potential annotation
-			final Annotation annotationPlugin = clazz.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass());
 
-			// Now check whether it is available
-			if (annotationPlugin != null) {
-				for (final Annotation rPort : (Annotation[]) this.classAndMethodContainer.getPluginRepositoryPortsMethod().invoke(annotationPlugin, new Object[0])) {
-					result.add(rPort);
-				}
+		// Get the potential annotation
+		final Annotation annotationPlugin = clazz.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass());
+
+		// Now check whether it is available
+		if (annotationPlugin != null) {
+			for (final Annotation rPort : (Annotation[]) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPluginRepositoryPortsMethod(),
+					annotationPlugin, new Annotation[0])) {
+				result.add(rPort);
 			}
-		} catch (final IllegalAccessException ex) {
-			CurrentAnalysisEditorBean.LOG.warn("Could not invoke method", ex);
-		} catch (final IllegalArgumentException ex) {
-			CurrentAnalysisEditorBean.LOG.warn("Could not invoke method", ex);
-		} catch (final InvocationTargetException ex) {
-			CurrentAnalysisEditorBean.LOG.warn("Could not invoke method", ex);
 		}
+
 		return result;
 	}
 
+	/**
+	 * Searches for displays within the given class and returns them.
+	 * 
+	 * @param clazz
+	 *            The class to be analyzed.
+	 * @return A list containing the available displays.
+	 */
 	public List<Annotation> getDisplays(final Class<?> clazz) {
 		final List<Annotation> result = new ArrayList<Annotation>();
 
@@ -550,9 +552,8 @@ public final class CurrentAnalysisEditorBean {
 	 * 
 	 * @param event
 	 *            The upload event.
-	 * @throws ProjectLoadException
 	 */
-	public void handleFileUpload(final FileUploadEvent event) throws ProjectLoadException {
+	public void handleFileUpload(final FileUploadEvent event) {
 		// Get the file from the event
 		final UploadedFile file = event.getFile();
 
@@ -567,25 +568,32 @@ public final class CurrentAnalysisEditorBean {
 			}
 			// Update our class loader and the available plugins & repositories
 			this.reloadClassLoader();
-			this.addToToolPalette(lib);
+			this.reloadClassesAndMethods();
+			this.addContentsToToolPalette(FSManager.getInstance().getURL(lib, this.projectName));
 		} catch (final LibraryAlreadyExistingException ex) {
 			CurrentAnalysisEditorBean.LOG.info("A library with the same name exists already.", ex);
 			CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_WARN, "A library with the same name exists already.");
 		} catch (final IOException ex) {
 			CurrentAnalysisEditorBean.LOG.error("An error occured while uploading the library.", ex);
 			CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while uploading the library.");
+		} catch (final ProjectLoadException ex) {
+			CurrentAnalysisEditorBean.LOG.error("An error occured while uploading the library.", ex);
+			CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while uploading the library.");
 		}
 	}
 
 	/**
-	 * This method delivers the available libraries of this project as a pair of strings. The first element is the name of the library, the second one te size in
-	 * MiBytes as human readable string.
+	 * This method delivers the available libraries of this project as a pair of strings. The first element is the name of the library, the second one the size in
+	 * MiBytes as human readable string. The first element is always the kieker-library.
 	 * 
 	 * @return The available libraries.
 	 */
 	public List<Pair<String, String>> getLibraries() {
 		synchronized (this) {
-			return FSManager.getInstance().getLibraries(this.projectName);
+			final List<Pair<String, String>> result = FSManager.getInstance().getLibraries(this.projectName);
+			result.add(0, new Pair<String, String>("Kieker", "N/A"));
+
+			return result;
 		}
 	}
 
@@ -594,7 +602,7 @@ public final class CurrentAnalysisEditorBean {
 	 * 
 	 * @return A list with all readers.
 	 */
-	public final List<Class<?>> getAvailableReaders() {
+	public final List<Class<AbstractReaderPlugin>> getAvailableReaders() {
 		return this.availableReaders;
 	}
 
@@ -603,7 +611,7 @@ public final class CurrentAnalysisEditorBean {
 	 * 
 	 * @return A list with all filter.
 	 */
-	public final List<Class<?>> getAvailableFilters() {
+	public final List<Class<AbstractFilterPlugin>> getAvailableFilters() {
 		return this.availableFilters;
 	}
 
@@ -612,7 +620,7 @@ public final class CurrentAnalysisEditorBean {
 	 * 
 	 * @return A list with all repositories.
 	 */
-	public final List<Class<?>> getAvailableRepositories() {
+	public final List<Class<AbstractRepository>> getAvailableRepositories() {
 		return this.availableRepositories;
 	}
 
@@ -629,6 +637,7 @@ public final class CurrentAnalysisEditorBean {
 				CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_INFO, "Project saved.");
 				// Update the time stamp!
 				this.resetTimeStamp();
+				this.modified = false;
 			} catch (final IOException ex) {
 				CurrentAnalysisEditorBean.LOG.error("An error occured while saving the project.", ex);
 				CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while saving the project.");
@@ -642,196 +651,95 @@ public final class CurrentAnalysisEditorBean {
 	}
 
 	/**
-	 * This method fills the displays of the given plugin. In other words: It tries to instantiate the given class and to extract the displays. If the instantiation
-	 * fails (for various reasons), the method informs the user and executes normally - without an exception.
+	 * This method fills the displays of the given plugin. In other words: It tries to extract the list of displays from the given class (using the annotations) and
+	 * to convert them into model instances.
 	 * 
 	 * @param clazz
 	 *            The class to be used as a base.
 	 * @param plugin
 	 *            The plugin to be filled.
-	 * @return true iff the plugin has been intialized properly.
 	 */
-	private boolean fillDisplays(final Class<AbstractPlugin> clazz, final MIPlugin plugin) {
+	private void fillDisplays(final Class<AbstractPlugin> clazz, final MIPlugin plugin) {
 		synchronized (this) {
-			try {
-				// Get the displays and convert them into model instances
-				final List<Annotation> displays = this.getDisplays(clazz);
-				for (final Annotation display : displays) {
-					final MIDisplay mDisplay = this.factory.createDisplay();
-					mDisplay.setName((String) this.classAndMethodContainer.getDisplayNameMethod().invoke(display, new Object[0]));
-					plugin.getDisplays().add(mDisplay);
-				}
-
-				return true;
-			} catch (final IllegalAccessException ex) {
-				CurrentAnalysisEditorBean.LOG.error("An error occured while loading the displays of the plugin.", ex);
-				CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the displays of the plugin.");
-				return false;
-			} catch (final ClassCastException ex) {
-				CurrentAnalysisEditorBean.LOG.error("An error occured while loading the displays of the plugin.", ex);
-				CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the displays of the plugin.");
-				return false;
-			} catch (final IllegalArgumentException ex) {
-				CurrentAnalysisEditorBean.LOG.error("An error occured while loading the displays of the plugin.", ex);
-				CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the displays of the plugin.");
-				return false;
-			} catch (final InvocationTargetException ex) {
-				CurrentAnalysisEditorBean.LOG.error("An error occured while loading the displays of the plugin.", ex);
-				CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the displays of the plugin.");
-				return false;
+			// Get the displays and convert them into model instances
+			final List<Annotation> displays = this.getDisplays(clazz);
+			for (final Annotation display : displays) {
+				final MIDisplay mDisplay = this.factory.createDisplay();
+				mDisplay.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getDisplayNameMethod(), display, "N/A"));
+				plugin.getDisplays().add(mDisplay);
 			}
 		}
 	}
 
 	/**
-	 * This method fills the ports of the given plugin. In other words: It tries to instantiate the given class and to extract the ports. If the instantiation fails
-	 * (for various reasons), the method informs the user and executes normally - without an exception.
+	 * This method fills the ports of the given plugin. In other words: It tries to extract the list of ports from the given class (using the annotations) and
+	 * to convert them into model instances.
 	 * 
 	 * @param clazz
 	 *            The class to be used as a base.
 	 * @param plugin
 	 *            The plugin to be filled.
-	 * @return true iff the plugin has been intialized properly.
 	 */
-	private boolean fillPorts(final Class<AbstractPlugin> clazz, final MIPlugin plugin) {
+	private void fillPorts(final Class<AbstractPlugin> clazz, final MIPlugin plugin) {
 		synchronized (this) {
-			try {
-				// Get the ports
-				final List<Annotation> inputPorts = this.getInputPorts(clazz);
-				final List<Annotation> outputPorts = this.getOutputPorts(clazz);
-				final List<Annotation> repositoryPorts = this.getRepositoryPorts(clazz);
-
-				// Add input ports
-				if (plugin instanceof MIFilter) {
-					for (final Annotation inputPort : inputPorts) {
-						final MIInputPort mInputPort = this.factory.createInputPort();
-						mInputPort.setName((String) this.classAndMethodContainer.getInputPortNameMethod().invoke(inputPort, new Object[0]));
-						mInputPort.setParent((MIFilter) plugin);
-					}
-				}
-
-				// Add output ports.
-				for (final Annotation outputPort : outputPorts) {
-					final MIOutputPort mOutputPort = this.factory.createOutputPort();
-					mOutputPort.setName((String) this.classAndMethodContainer.getOutputPortNameMethod().invoke(outputPort, new Object[0]));
-					mOutputPort.setParent(plugin);
+			// Get the ports
+			final List<Annotation> inputPorts = this.getInputPorts(clazz);
+			final List<Annotation> outputPorts = this.getOutputPorts(clazz);
+			final List<Annotation> repositoryPorts = this.getRepositoryPorts(clazz);
+
+			// Add input ports
+			if (plugin instanceof MIFilter) {
+				for (final Annotation inputPort : inputPorts) {
+					final MIInputPort mInputPort = this.factory.createInputPort();
+					mInputPort.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getInputPortNameMethod(), inputPort, "N/A"));
+					mInputPort.setParent((MIFilter) plugin);
 				}
+			}
 
-				// Add repository ports.
-				for (final Annotation repositoryPort : repositoryPorts) {
-					final MIRepositoryConnector mConnector = this.factory.createRepositoryConnector();
-					mConnector.setName((String) this.classAndMethodContainer.getRepositoryPortNameMethod().invoke(repositoryPort, new Object[0]));
-					plugin.getRepositories().add(mConnector);
-				}
+			// Add output ports.
+			for (final Annotation outputPort : outputPorts) {
+				final MIOutputPort mOutputPort = this.factory.createOutputPort();
+				mOutputPort.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getOutputPortNameMethod(), outputPort, "N/A"));
+				mOutputPort.setParent(plugin);
+			}
 
-				return true;
-
-			} catch (final IllegalAccessException ex) {
-				CurrentAnalysisEditorBean.LOG.error("An error occured while loading the ports of the plugin.", ex);
-				CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the ports of the plugin.");
-				return false;
-			} catch (final ClassCastException ex) {
-				CurrentAnalysisEditorBean.LOG.error("An error occured while loading the ports of the plugin.", ex);
-				CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the ports of the plugin.");
-				return false;
-			} catch (final IllegalArgumentException ex) {
-				CurrentAnalysisEditorBean.LOG.error("An error occured while loading the ports of the plugin.", ex);
-				CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the ports of the plugin.");
-				return false;
-			} catch (final InvocationTargetException ex) {
-				CurrentAnalysisEditorBean.LOG.error("An error occured while loading the ports of the plugin.", ex);
-				CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the ports of the plugin.");
-				return false;
+			// Add repository ports.
+			for (final Annotation repositoryPort : repositoryPorts) {
+				final MIRepositoryConnector mConnector = this.factory.createRepositoryConnector();
+				mConnector.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getRepositoryPortNameMethod(), repositoryPort,
+						"N/A"));
+				plugin.getRepositories().add(mConnector);
 			}
 		}
 	}
 
 	/**
-	 * This method fills the properties of the given repository. In other words: It tries to instantiate the given class and to extract the configuration keys. If
-	 * the instantiation fails (for various reasons), the method informs the user and executes normally - without an exception.
+	 * This method fills the properties of the given repository or plugin. In other words: It tries to extract the list of properties from the given class (using the
+	 * annotations) and to convert them into model instances.
 	 * 
 	 * @param clazz
 	 *            The class to be used as a base.
-	 * @param repository
-	 *            The repository to be filled.
-	 * @return true iff the repository has been intialized properly.
+	 * @param component
+	 *            The component to be filled.
 	 */
-	private boolean fillProperties(final Class<AbstractRepository> clazz, final MIRepository repository) {
-		try {
-			// Get the default configuration and use it to initialize the model repository
-			final List<Annotation> properties = this.getProperties(clazz);
+	private void fillProperties(final Class<?> clazz, final EObject component) {
+		// Get the default configuration and use it to initialize the model repository
+		final List<Annotation> properties = this.getProperties(clazz);
 
-			for (final Annotation property : properties) {
-				final MIProperty mProperty = this.factory.createProperty();
+		for (final Annotation property : properties) {
+			final MIProperty mProperty = this.factory.createProperty();
 
-				mProperty.setName((String) this.classAndMethodContainer.getPropertyNameMethod().invoke(property, new Object[0]));
-				mProperty.setValue((String) this.classAndMethodContainer.getPropertyDefaultValueMethod().invoke(property, new Object[0]));
+			mProperty.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPropertyNameMethod(), property, "N/A"));
+			mProperty.setValue((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPropertyDefaultValueMethod(), property, "N/A"));
+			mProperty.setDescription((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPropertyDefaultValueMethod(), property, "N/A"));
 
-				repository.getProperties().add(mProperty);
+			if (component instanceof MIPlugin) {
+				((MIPlugin) component).getProperties().add(mProperty);
+			} else {
+				((MIRepository) component).getProperties().add(mProperty);
 			}
-
-			return true;
-		} catch (final IllegalAccessException ex) {
-			CurrentAnalysisEditorBean.LOG.error("An error occured while loading the properties of the repository.", ex);
-			CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the properties of the repository.");
-			return false;
-		} catch (final ClassCastException ex) {
-			CurrentAnalysisEditorBean.LOG.error("An error occured while loading the properties of the repository.", ex);
-			CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the properties of the repository.");
-			return false;
-		} catch (final IllegalArgumentException ex) {
-			CurrentAnalysisEditorBean.LOG.error("An error occured while loading the properties of the repository.", ex);
-			CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the properties of the repository.");
-			return false;
-		} catch (final InvocationTargetException ex) {
-			CurrentAnalysisEditorBean.LOG.error("An error occured while loading the properties of the repository.", ex);
-			CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the properties of the repository.");
-			return false;
 		}
-	}
 
-	/**
-	 * This method fills the properties of the given plugin. In other words: It tries to instantiate the given class and to extract the configuration keys. If
-	 * the instantiation fails (for various reasons), the method informs the user and executes normally - without an exception.
-	 * 
-	 * @param clazz
-	 *            The class to be used as a base.
-	 * @param plugin
-	 *            The plugin to be filled.
-	 * @return true iff the plugin has been intialized properly.
-	 */
-	private boolean fillProperties(final Class<AbstractPlugin> clazz, final MIPlugin plugin) {
-		try {
-			// Get the default configuration and use it to initialize the model plugin
-			final List<Annotation> properties = this.getProperties(clazz);
-
-			for (final Annotation property : properties) {
-				final MIProperty mProperty = this.factory.createProperty();
-
-				mProperty.setName((String) this.classAndMethodContainer.getPropertyNameMethod().invoke(property, new Object[0]));
-				mProperty.setValue((String) this.classAndMethodContainer.getPropertyDefaultValueMethod().invoke(property, new Object[0]));
-				mProperty.setDescription((String) this.classAndMethodContainer.getPropertyDescriptionMethod().invoke(property, new Object[0]));
-				plugin.getProperties().add(mProperty);
-			}
-
-			return true;
-		} catch (final IllegalAccessException ex) {
-			CurrentAnalysisEditorBean.LOG.error("An error occured while loading the properties of the plugin.", ex);
-			CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the properties of the plugin.");
-			return false;
-		} catch (final ClassCastException ex) {
-			CurrentAnalysisEditorBean.LOG.error("An error occured while loading the properties of the plugin.", ex);
-			CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the properties of the plugin.");
-			return false;
-		} catch (final IllegalArgumentException ex) {
-			CurrentAnalysisEditorBean.LOG.error("An error occured while loading the properties of the plugin.", ex);
-			CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the properties of the plugin.");
-			return false;
-		} catch (final InvocationTargetException ex) {
-			CurrentAnalysisEditorBean.LOG.error("An error occured while loading the properties of the plugin.", ex);
-			CurrentAnalysisEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the properties of the plugin.");
-			return false;
-		}
 	}
 
 	/**
@@ -846,15 +754,13 @@ public final class CurrentAnalysisEditorBean {
 		repository.setClassname(clazz.getName());
 		repository.setName(clazz.getSimpleName());
 
-		final boolean check = this.fillProperties(clazz, repository);
-		// Make sure that everything has been loaded correctly. If something went wrong, we don't add the component to our model
-		if (check) {
-			synchronized (this) {
-				// Add it to the project - and to the graph
-				this.project.getRepositories().add(repository);
-				this.currentAnalysisEditorGraphBean.addRepository(repository);
-				this.currentAnalysisEditorGraphBean.refreshGraph();
-			}
+		this.fillProperties(clazz, repository);
+		synchronized (this) {
+			// Add it to the project - and to the graph
+			this.project.getRepositories().add(repository);
+			this.currentAnalysisEditorGraphBean.addRepository(repository);
+			this.currentAnalysisEditorGraphBean.refreshGraph();
+			this.modified = true;
 		}
 	}
 
@@ -875,25 +781,22 @@ public final class CurrentAnalysisEditorBean {
 		plugin.setClassname(clazz.getName());
 		plugin.setName(clazz.getSimpleName());
 
-		boolean check = true;
-		check &= this.fillProperties(clazz, plugin);
-		check &= this.fillPorts(clazz, plugin);
-		check &= this.fillDisplays(clazz, plugin);
+		this.fillProperties(clazz, plugin);
+		this.fillPorts(clazz, plugin);
+		this.fillDisplays(clazz, plugin);
 
-		// Make sure that everything has been loaded correctly. If something went wrong, we don't add the component to our model
-		if (check) {
-			synchronized (this) {
-				// Add it to the project
-				this.project.getPlugins().add(plugin);
+		synchronized (this) {
+			// Add it to the project
+			this.project.getPlugins().add(plugin);
 
-				// Add the element to the graph
-				if (plugin instanceof MIReader) {
-					this.currentAnalysisEditorGraphBean.addReader((MIReader) plugin);
-				} else {
-					this.currentAnalysisEditorGraphBean.addFilter((MIFilter) plugin);
-				}
-				this.currentAnalysisEditorGraphBean.refreshGraph();
+			// Add the element to the graph
+			if (plugin instanceof MIReader) {
+				this.currentAnalysisEditorGraphBean.addReader((MIReader) plugin);
+			} else {
+				this.currentAnalysisEditorGraphBean.addFilter((MIFilter) plugin);
 			}
+			this.currentAnalysisEditorGraphBean.refreshGraph();
+			this.modified = true;
 		}
 	}
 
@@ -904,7 +807,7 @@ public final class CurrentAnalysisEditorBean {
 	 */
 	public EObject getSelectedPlugin() {
 		synchronized (this) {
-			return this.selectedNode;
+			return this.selectedComponent;
 		}
 	}
 
@@ -924,10 +827,10 @@ public final class CurrentAnalysisEditorBean {
 			result.add("ClassName");
 
 			// Get the original properties of the plugin
-			if (this.selectedNode instanceof MIPlugin) {
-				result.addAll(((MIPlugin) this.selectedNode).getProperties());
+			if (this.selectedComponent instanceof MIPlugin) {
+				result.addAll(((MIPlugin) this.selectedComponent).getProperties());
 			} else {
-				result.addAll(((MIRepository) this.selectedNode).getProperties());
+				result.addAll(((MIRepository) this.selectedComponent).getProperties());
 			}
 
 			return result;
@@ -973,11 +876,11 @@ public final class CurrentAnalysisEditorBean {
 	 */
 	public String getCurrentPluginName() {
 		synchronized (this) {
-			if (this.selectedNode != null) {
-				if (this.selectedNode instanceof MIPlugin) {
-					return ((MIPlugin) this.selectedNode).getName();
+			if (this.selectedComponent != null) {
+				if (this.selectedComponent instanceof MIPlugin) {
+					return ((MIPlugin) this.selectedComponent).getName();
 				} else {
-					return ((MIRepository) this.selectedNode).getName();
+					return ((MIRepository) this.selectedComponent).getName();
 				}
 			} else {
 				return "";
@@ -1016,12 +919,12 @@ public final class CurrentAnalysisEditorBean {
 				this.currentAnalysisEditorGraphBean.addFilter((MIFilter) plugin);
 			}
 		}
-		this.currentAnalysisEditorGraphBean.initGraph();
+
 		for (final MIRepository repository : this.project.getRepositories()) {
 			this.currentAnalysisEditorGraphBean.addRepository(repository);
 		}
 
-		// Now initialize the connections between filters
+		// Now initialize the connections between filters...
 		for (final MIPlugin plugin : this.project.getPlugins()) {
 			for (final MIOutputPort oPort : plugin.getOutputPorts()) {
 				for (final MIInputPort iPort : oPort.getSubscribers()) {
@@ -1030,11 +933,18 @@ public final class CurrentAnalysisEditorBean {
 			}
 		}
 
-		// TODO Connections between filters and repositories
+		// ...and between filters and repositories
+		for (final MIPlugin plugin : this.project.getPlugins()) {
+			for (final MIRepositoryConnector rPort : plugin.getRepositories()) {
+				// It is possible that the connected repository is null, if it hasn't been set yet. Check this.
+				if (rPort.getRepository() != null) {
+					this.currentAnalysisEditorGraphBean.addConnection(plugin, rPort.getRepository(), rPort);
+				}
+			}
+		}
 
 		this.currentAnalysisEditorGraphBean.initListeners();
-
-		// This command is here necessary because of a current bug
+		this.currentAnalysisEditorGraphBean.addEdgeConstraints();
 
 		// Repaint the graph
 		this.currentAnalysisEditorGraphBean.refreshGraph();
@@ -1042,7 +952,7 @@ public final class CurrentAnalysisEditorBean {
 
 	public void nodeSelected(final EObject node) {
 		synchronized (this) {
-			this.selectedNode = node;
+			this.selectedComponent = node;
 		}
 	}
 
@@ -1079,8 +989,8 @@ public final class CurrentAnalysisEditorBean {
 			}
 
 			// Unselect the currently selected node if it is the one which has just been removed
-			if (this.selectedNode == node) {
-				this.selectedNode = null; // NOPMD
+			if (this.selectedComponent == node) {
+				this.selectedComponent = null; // NOPMD
 			}
 		}
 	}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorGraphBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorGraphBean.java
index d311e64a..f687baf0 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorGraphBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorGraphBean.java
@@ -64,9 +64,9 @@ public class CurrentAnalysisEditorGraphBean {
 	 */
 	private static final String JS_CMD_CREATE_GRAPH_VAR = "var graph = GraphFlow();";
 	/**
-	 * This is the javascript code to initialize the visual graph.
+	 * This is the javascript code to add edge constraints to the graph.
 	 */
-	private static final String JS_CMD_INIT_GRAPH = "graph.initGraph(null);";
+	private static final String JS_CMD_ADD_EDGE_CONSTRAINTS = "graph.addEdgeConstraints()";
 	/**
 	 * This is the javasscript code to add the click listener to the graph.
 	 */
@@ -143,15 +143,7 @@ public class CurrentAnalysisEditorGraphBean {
 	}
 
 	/**
-	 * Initializes the graph.
-	 */
-	public void initGraph() {
-		RequestContext.getCurrentInstance().execute(CurrentAnalysisEditorGraphBean.JS_CMD_INIT_GRAPH);
-
-	}
-
-	/**
-	 * Initializes the listeners for the graph
+	 * Initializes the listeners for the graph.
 	 */
 	public void initListeners() {
 		RequestContext.getCurrentInstance().execute(CurrentAnalysisEditorGraphBean.JS_CMD_ADD_CLICK_LISTENER);
@@ -160,6 +152,13 @@ public class CurrentAnalysisEditorGraphBean {
 		RequestContext.getCurrentInstance().execute(CurrentAnalysisEditorGraphBean.JS_CMD_ADD_REMOVE_EDGE_LISTENER);
 	}
 
+	/**
+	 * Adds the edge constraints to the graph.
+	 */
+	public void addEdgeConstraints() {
+		RequestContext.getCurrentInstance().execute(CurrentAnalysisEditorGraphBean.JS_CMD_ADD_EDGE_CONSTRAINTS);
+	}
+
 	/**
 	 * Refreshes the graph after changes have been made.
 	 */
@@ -222,6 +221,21 @@ public class CurrentAnalysisEditorGraphBean {
 				this.assembleGraphPortID(destination, inputPort), ""));
 	}
 
+	/**
+	 * This method adds a connection between a filter and a repository to the graph.
+	 * 
+	 * @param source
+	 *            The source plugin.
+	 * @param repository
+	 *            The destination repository.
+	 * @param port
+	 *            The repository port.
+	 */
+	public void addConnection(final MIPlugin source, final MIRepository destination, final MIRepositoryConnector port) {
+		RequestContext.getCurrentInstance().execute(String.format(CurrentAnalysisEditorGraphBean.JS_CMD_ADD_EDGE, this.assembleGraphPortID(source, port),
+				this.assembleGraphPortID(destination), ""));
+	}
+
 	/**
 	 * This method assembles the string containing the given ports.
 	 * 
@@ -251,8 +265,8 @@ public class CurrentAnalysisEditorGraphBean {
 	/**
 	 * This method assembles the string containing the available repository ports of the given plugin.
 	 * 
-	 * @param plugin
-	 *            The plugin whose repository ports will be used.
+	 * @param ports
+	 *            The ports which will be used.
 	 * @return A string containing the JS commands to create the repository ports.
 	 */
 	private String assembleGraphRepositoryPortString(final EList<MIRepositoryConnector> ports) {
@@ -308,6 +322,30 @@ public class CurrentAnalysisEditorGraphBean {
 		return this.componentMap.get(plugin) + "." + this.componentMap.get(port);
 	}
 
+	/**
+	 * This method assembles the ID of the port for the graph based on the given parameters.
+	 * 
+	 * @param plugin
+	 *            The parent plugin of the port.
+	 * @param port
+	 *            The port itself.
+	 * @return The ID for the port within the graph
+	 */
+	private Object assembleGraphPortID(final MIPlugin plugin, final MIRepositoryConnector port) {
+		return this.componentMap.get(plugin) + "." + this.componentMap.get(port);
+	}
+
+	/**
+	 * This method assembles the ID of the port for the graph based on the given parameters.
+	 * 
+	 * @param repository
+	 *            The parent repository of the port.
+	 * @return The ID for the port within the graph
+	 */
+	private Object assembleGraphPortID(final MIRepository repository) {
+		return this.componentMap.get(repository) + "." + CurrentAnalysisEditorGraphBean.REPOSITORY_INPUT_PORT;
+	}
+
 	/**
 	 * Assembles a human-readable string of the given repository, which can also be used as a graph ID.
 	 * 
@@ -375,6 +413,10 @@ public class CurrentAnalysisEditorGraphBean {
 		}
 	}
 
+	/**
+	 * This is the action which can be called from the javascript code to show that an edge has been created. It informs the connected
+	 * {@link CurrentAnalysisEditorBean} about this.
+	 */
 	public void edgeCreated() {
 		// Get the parameters
 		final Map<String, String> paramMap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
@@ -407,6 +449,10 @@ public class CurrentAnalysisEditorGraphBean {
 		}
 	}
 
+	/**
+	 * This is the action which can be called from the javascript code to show that an edge has been removed. It informs the connected
+	 * {@link CurrentAnalysisEditorBean} about this.
+	 */
 	public void edgeRemoved() {
 		// Get the parameters
 		final Map<String, String> paramMap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitEditorBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitEditorBean.java
index a6df7f6b..c624674d 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitEditorBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitEditorBean.java
@@ -49,6 +49,7 @@ import kieker.webgui.beans.application.ProjectsBean;
 import kieker.webgui.common.FSManager;
 import kieker.webgui.common.Global;
 import kieker.webgui.common.exception.NewerProjectException;
+import kieker.webgui.common.exception.ProjectLoadException;
 
 import org.primefaces.context.RequestContext;
 import org.primefaces.event.TabChangeEvent;
@@ -123,14 +124,19 @@ public class CurrentCockpitEditorBean {
 	 */
 	public void initalize() {
 		synchronized (this) {
-			// 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();
+			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();
+					}
 				}
+			} catch (final ProjectLoadException ex) {
+				CurrentCockpitEditorBean.LOG.error("An error occured while loading the project.", ex);
+				CurrentCockpitEditorBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project.");
 			}
 		}
 	}
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 a0ca7527..a3bf7c1e 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
@@ -39,6 +39,7 @@ import kieker.webgui.common.exception.AnalysisAlreadyStartedException;
 import kieker.webgui.common.exception.AnalysisInstantiationException;
 import kieker.webgui.common.exception.AnalysisNotInstantiatedException;
 import kieker.webgui.common.exception.AnalysisNotStartedException;
+import kieker.webgui.common.exception.ProjectLoadException;
 
 /**
  * /**
@@ -112,10 +113,15 @@ public class CurrentControllerBean {
 	 */
 	public void initalize() {
 		synchronized (this) {
-			// 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);
+			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);
+				}
+			} catch (final ProjectLoadException ex) {
+				CurrentControllerBean.LOG.error("An error occured while loading the project.", ex);
+				CurrentControllerBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project.");
 			}
 		}
 	}
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 7ca07997..d4d764f0 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java
@@ -24,7 +24,6 @@ import java.io.IOException;
 import java.util.concurrent.ConcurrentHashMap;
 
 import kieker.analysis.AnalysisController;
-import kieker.analysis.model.analysisMetaModel.MIProject;
 import kieker.common.logging.Log;
 import kieker.common.logging.LogFactory;
 import kieker.webgui.common.exception.AnalysisAlreadyInstantiatedException;
@@ -139,10 +138,11 @@ public final class ACManager {
 	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);
+				FSManager.getInstance().openProject(project);
+				FSManager.getInstance().getClassLoader(project);
 
-				this.analyses.put(project, new Analysis(classLoader, modelProject));
+				// TODO
+				// this.analyses.put(project, new Analysis(classLoader, modelProject));
 			} else {
 				throw new AnalysisAlreadyInstantiatedException("The analysis has already been initialized.");
 			}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/Analysis.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/Analysis.java
index 614566c3..78a0f65b 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/Analysis.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/Analysis.java
@@ -1,5 +1,6 @@
 package kieker.webgui.common;
 
+import java.io.File;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -8,9 +9,6 @@ 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;
@@ -26,17 +24,17 @@ public class Analysis {
 	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 modelProject;
 	private final Object analysisController;
 	private final Object analysisControllerThread;
 	private final UpdateDisplaysThread updateDisplaysThread;
 
-	public Analysis(final ClassLoader classLoader, final MIProject modelProject) throws AnalysisInstantiationException {
+	public Analysis(final ClassLoader classLoader, final File projectFile) throws AnalysisInstantiationException {
 		try {
-			this.modelProject = modelProject;
 			this.classAndMethodContainer = new ClassAndMethodContainer(classLoader);
 
 			final Method createMethod = this.classAndMethodContainer.getAnalysisControllerCreateAnalysisController();
+			this.modelProject = ClassAndMethodContainer.invokeClassMethod(this.classAndMethodContainer.getAnalysisControllerLoadFromFile(), null, projectFile);
 			final Object controllerAndMapping = ClassAndMethodContainer.invokeClassMethod(createMethod, null, this.modelProject, classLoader);
 			this.analysisController = ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getAnalysisControllerWithMappingGetController(),
 					controllerAndMapping, null);
@@ -76,7 +74,7 @@ public class Analysis {
 		synchronized (this) {
 			try {
 				this.classAndMethodContainer.getAnalysisControllerThreadTerminate().invoke(this.analysisControllerThread, new Object[0]);
-				this.updateDisplaysThread.terminate();
+				// this.updateDisplaysThread.terminate();
 
 				this.classAndMethodContainer.getAnalysisControllerThreadJoin().invoke(this.analysisControllerThread, Analysis.MAX_THREAD_WAIT_TIME_MS);
 				this.updateDisplaysThread.join(Analysis.MAX_THREAD_WAIT_TIME_MS);
@@ -137,40 +135,40 @@ public class Analysis {
 		@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());
+			// 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);
-					 * }
-					 * }
-					 */
-				}
-			}
+			// 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);
+			 * }
+			 * }
+			 */
+			// }
+			// }
 		}
 
 		/**
@@ -222,35 +220,35 @@ public class Analysis {
 		@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);
-						// }
-					}
-				}
+			// 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;
-				}
-			}
+			// 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/ClassAndMethodContainer.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ClassAndMethodContainer.java
index a9fc8768..d1c0410c 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/ClassAndMethodContainer.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ClassAndMethodContainer.java
@@ -19,6 +19,7 @@
  ***************************************************************************/
 package kieker.webgui.common;
 
+import java.io.File;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
@@ -218,6 +219,10 @@ public final class ClassAndMethodContainer {
 	 * This is the description()-method of the class equivalence of {@link Property}.
 	 */
 	private final Method propertyDescriptionMethod;
+	/**
+	 * This is the loadFromFile(File)-method of the class equivalence of {@link AnalysisController}.
+	 */
+	private final Method analysisControllerLoadFromFile;
 	/**
 	 * This is the constructor for {@link AnalysisControllerThread}, which gets an instance of {@link AnalysisController}.
 	 */
@@ -276,8 +281,9 @@ public final class ClassAndMethodContainer {
 
 			// 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);
+			this.analysisControllerLoadFromFile = this.analysisControllerClass.getMethod("loadFromFile", File.class);
+
+			this.analysisControllerCreateAnalysisController = this.analysisControllerClass.getMethod("createAnalysisController", miProjectClass, ClassLoader.class);
 
 			// Another special case as the parameter is a long
 			final Method[] methods = this.analysisControllerThreadClass.getMethods();
@@ -652,11 +658,19 @@ public final class ClassAndMethodContainer {
 	 * 
 	 * @return The current value for the field.
 	 */
-
 	public Constructor<?> getAnalysisControllerThreadConstructor() {
 		return this.analysisControllerThreadConstructor;
 	}
 
+	/**
+	 * The getter-method for the field {@link ClassAndMethodContainer#analysisControllerLoadFromFile}.
+	 * 
+	 * @return The current value for the field.
+	 */
+	public Method getAnalysisControllerLoadFromFile() {
+		return this.analysisControllerLoadFromFile;
+	}
+
 	/**
 	 * 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.
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/FSManager.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/FSManager.java
index 01d1053d..58c79d60 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/FSManager.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/FSManager.java
@@ -211,6 +211,12 @@ public final class FSManager { // NOCS (Class Data Abstraction Coupling, Class F
 		}
 	}
 
+	public Object openProject(final String project, final ClassAndMethodContainer classAndMethodContainer) {
+		// TODO Correct and synchronize
+		// return ClassAndMethodContainer.invokeClassMethod(this.classAndMethodContainer.getAnalysisControllerLoadFromFile(), null, projectFile);
+		return null;
+	}
+
 	/**
 	 * This method tries to save the given project.
 	 * 
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginFinder.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginFinder.java
index 7a987557..c55b64de 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginFinder.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginFinder.java
@@ -26,6 +26,8 @@ import java.util.List;
 import java.util.jar.JarEntry;
 import java.util.jar.JarInputStream;
 
+import kieker.analysis.plugin.AbstractPlugin;
+import kieker.analysis.repository.AbstractRepository;
 import kieker.webgui.common.exception.ProjectLoadException;
 
 /**
@@ -59,19 +61,19 @@ public final class PluginFinder {
 	 *            The url for the jar.
 	 * @return A list containing all available repository-classes or null, if an exception occurred.
 	 */
-	public List<Class<?>> getAllRepositoriesWithinJar(final URL url) {
+	public List<Class<AbstractRepository>> getAllRepositoriesWithinJar(final URL url) {
 		// Get a list containing all available classes within the given jar
 		final List<Class<?>> clazzes = this.getAllClassesWithinJar(url);
 
-		List<Class<?>> result = null;
+		List<Class<AbstractRepository>> result = null;
 
 		if (clazzes != null) {
-			result = new ArrayList<Class<?>>();
+			result = new ArrayList<Class<AbstractRepository>>();
 			for (final Class<?> clazz : clazzes) {
 				// This is the cast resulting in an unchecked cast warning.
 				if (clazz.isAnnotationPresent(this.classAndMethodContainer.getRepositoryAnnotationClass())
 						&& this.classAndMethodContainer.getAbstractRepositoryClass().isAssignableFrom(clazz)) {
-					result.add(clazz);
+					result.add((Class<AbstractRepository>) clazz);
 				}
 			}
 		}
@@ -89,17 +91,17 @@ public final class PluginFinder {
 	 *            The class loader used to load the classes.
 	 * @return A list containing all available plugin-classes or null, if an exception occurred.
 	 */
-	public List<Class<?>> getAllPluginsWithinJar(final URL url) {
+	public List<Class<AbstractPlugin>> getAllPluginsWithinJar(final URL url) {
 		final List<Class<?>> clazzes = this.getAllClassesWithinJar(url);
-		List<Class<?>> result = null;
+		List<Class<AbstractPlugin>> result = null;
 
 		if (clazzes != null) {
-			result = new ArrayList<Class<?>>();
+			result = new ArrayList<Class<AbstractPlugin>>();
 			for (final Class<?> clazz : clazzes) {
 				// This is the cast resulting in an unchecked cast warning.
 				if (clazz.isAnnotationPresent(this.classAndMethodContainer.getPluginAnnotationClass())
 						&& this.classAndMethodContainer.getAbstractPluginClass().isAssignableFrom(clazz)) {
-					result.add(clazz);
+					result.add((Class<AbstractPlugin>) clazz);
 				}
 			}
 		}
diff --git a/Kieker.WebGUI/src/main/webapp/js/flowEditor.js b/Kieker.WebGUI/src/main/webapp/js/flowEditor.js
index d6940388..fbd72d47 100644
--- a/Kieker.WebGUI/src/main/webapp/js/flowEditor.js
+++ b/Kieker.WebGUI/src/main/webapp/js/flowEditor.js
@@ -71,20 +71,7 @@ function GraphFlow(){
 	/** This array stores all Nodes and is initialized with a dummy,
 		used for drawing edges between a node and the mousepointer.
 		*/
-	var json = [ null, null, null, null, null, null, null, null, null, null, 
-			{
-			  "adjacencies": [], 
-			  "data": {
-				"$dim": 0,
-				"$type": "none",
-				"&xPos": 0,
-				"&typeSelected" : null,
-				"&yPos": 0,
-			  }, 
-			  "id": "#DUMMY_MOUSE_NODE", 
-			  "name": "",
-			  "alpha": 0
-		}];
+	var json;
 		
 	/** Used for managing space for node creation/deletion
 		since the array is divided into to parts, adding and removing nodes
@@ -1023,15 +1010,24 @@ function GraphFlow(){
 		}); 
   }
     
-  
   /**
 	Initializes the Graph
 	*/
-  this.initGraph = function(graph){
-  
-	  if(graph != null){
-		json = graph;
-	  }
+  this.initGraph = function(){
+	json = [ null, null, null, null, null, null, null, null, null, null, 
+			{
+			  "adjacencies": [], 
+			  "data": {
+				"$dim": 0,
+				"$type": "none",
+				"&xPos": 0,
+				"&typeSelected" : null,
+				"&yPos": 0,
+			  }, 
+			  "id": "#DUMMY_MOUSE_NODE", 
+			  "name": "",
+			  "alpha": 0
+		}];
 	  
 	  fd = new $jit.FlowGraph({
 		//id of the visualization container
@@ -1360,13 +1356,15 @@ function GraphFlow(){
 	  });
 	  
 	  // load JSON data.
-	  fd.loadGraphFlowJSON(json,0);
+	  fd.loadGraphFlowJSON(json,jsonCapacity.max);
 	  // compute positions
 	  refresh();
 	  // end
 	  //alert("final wut:"+fd.nodeSizeModifier);
 	}
 	
+	// initialize graph
+	initGraph();
 	return this;
 }
 
@@ -1428,9 +1426,6 @@ function init(){
 									
 								   [{"name":"outputPort", "id":"op1"}]);
 								   
-	// create graph
-	graph.initGraph(null);
-	
 	// add nodes after graph creation
 	var node2 = {"id":"superNode2", 
 					  "name":"Super Repo", 
diff --git a/Kieker.WebGUI/src/main/webapp/js/jit.js b/Kieker.WebGUI/src/main/webapp/js/jit.js
index 951e6d3c..0ef47b26 100644
--- a/Kieker.WebGUI/src/main/webapp/js/jit.js
+++ b/Kieker.WebGUI/src/main/webapp/js/jit.js
@@ -18082,7 +18082,7 @@ $jit.FlowGraph.$extend = true;
 		
 		// add the label
 		// apparently this throws an error on FireFox...
-		/*var label = adj.data.$label;
+		var label = adj.data.$label;
 		if(label != undefined){
 			var ctx = canvas.getCtx();
 			ctx.font = (1.23 * dim)+"px Arial";
@@ -18090,7 +18090,7 @@ $jit.FlowGraph.$extend = true;
 			var	midX = (from.x + to.x - ctx.measureText(label).width) / 2,
 				midY = (from.y + to.y -dim) / 2;
 			ctx.fillText(label, midX, midY);
-		}*/
+		}
       },
       'contains': function(adj, pos) {
 			return false;
-- 
GitLab