diff --git a/Kieker.WebGUI/.settings/org.eclipse.jdt.core.prefs b/Kieker.WebGUI/.settings/org.eclipse.jdt.core.prefs
index 1217752323225e12414fa2158831026f60470d85..6c11a6dcbcd0592369564c1556361e7d71854743 100644
--- a/Kieker.WebGUI/.settings/org.eclipse.jdt.core.prefs
+++ b/Kieker.WebGUI/.settings/org.eclipse.jdt.core.prefs
@@ -120,7 +120,7 @@ org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
 org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
 org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
 org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/ComponentListContainer.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ComponentListContainer.java
new file mode 100644
index 0000000000000000000000000000000000000000..a76e74b116dc41b42823de0ea3b94b63753728a7
--- /dev/null
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ComponentListContainer.java
@@ -0,0 +1,76 @@
+/***************************************************************************
+ * Copyright 2012 Kieker Project (http://kieker-monitoring.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ***************************************************************************/
+package kieker.webgui.common;
+
+import java.util.List;
+
+/**
+ * This class is a container for multiple {@link PluginContainer} or {@link RepositoryContainer} instances. For each of the component type (reader, filter,
+ * repository) there is exactly one list available. This class will mostly be used to deliver a set of available components for a project. A bean using them could
+ * for example copy the available instances.
+ * 
+ * @author Nils Christian Ehmke
+ */
+public class ComponentListContainer {
+
+	private final List<PluginContainer> readers;
+	private final List<PluginContainer> filters;
+	private final List<RepositoryContainer> repositories;
+
+	/**
+	 * Creates a new instance of this class using the given parameters.
+	 * 
+	 * @param readers
+	 *            The list containing the readers.
+	 * @param filters
+	 *            The list containing the filters.
+	 * @param repositories
+	 *            The list containing the repositories.
+	 */
+	public ComponentListContainer(final List<PluginContainer> readers, final List<PluginContainer> filters, final List<RepositoryContainer> repositories) {
+		this.readers = readers;
+		this.filters = filters;
+		this.repositories = repositories;
+	}
+
+	/**
+	 * Getter for the property {@link ComponentListContainer#readers}.
+	 * 
+	 * @return The current value of the property.
+	 */
+	public List<PluginContainer> getReaders() {
+		return this.readers;
+	}
+
+	/**
+	 * Getter for the property {@link ComponentListContainer#filters}.
+	 * 
+	 * @return The current value of the property.
+	 */
+	public List<PluginContainer> getFilters() {
+		return this.filters;
+	}
+
+	/**
+	 * Getter for the property {@link ComponentListContainer#repositories}.
+	 * 
+	 * @return The current value of the property.
+	 */
+	public List<RepositoryContainer> getRepositories() {
+		return this.repositories;
+	}
+
+}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/EnvironmentLoaderListener.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/EnvironmentLoaderListener.java
index 77ace76e3e418d60222ce94ea1bd0909257b315a..d6ce666efb51fd54577bbee5f5a34d4791aa0620 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/EnvironmentLoaderListener.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/EnvironmentLoaderListener.java
@@ -39,11 +39,21 @@ public class EnvironmentLoaderListener implements ServletContextListener {
 		// No code necessary
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
+	 */
 	@Override
 	public void contextDestroyed(final ServletContextEvent event) {
 		// No code necessary
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
+	 */
 	@Override
 	public void contextInitialized(final ServletContextEvent event) {
 		// Before setting the logging property, use the log factory to make sure that the log entries of the WebGUI itself will be shown in the terminal
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/IComponentContainer.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/IComponentContainer.java
new file mode 100644
index 0000000000000000000000000000000000000000..9abf5a905c6bae75d96388f8e35a708cbc8fc753
--- /dev/null
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/IComponentContainer.java
@@ -0,0 +1,34 @@
+/***************************************************************************
+ * Copyright 2012 Kieker Project (http://kieker-monitoring.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ***************************************************************************/
+package kieker.webgui.common;
+
+/**
+ * This is the interface for component containers of different types (plugins and repositories). It exists to have a common base for the implementing classes.
+ * 
+ * @author Nils Christian Ehmke
+ */
+public interface IComponentContainer {
+
+	/**
+	 * Delivers the description of the given property.
+	 * 
+	 * @param property
+	 *            The property name.
+	 * @return The human readable description of the property.
+	 */
+	public String getPropertyDescription(final String property);
+
+}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginContainer.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginContainer.java
new file mode 100644
index 0000000000000000000000000000000000000000..6bcfaff215b28f512052ce2410325809153e063d
--- /dev/null
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginContainer.java
@@ -0,0 +1,211 @@
+/***************************************************************************
+ * Copyright 2012 Kieker Project (http://kieker-monitoring.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ***************************************************************************/
+
+package kieker.webgui.common;
+
+import java.util.Map;
+
+import kieker.analysis.model.analysisMetaModel.MIAnalysisMetaModelFactory;
+import kieker.analysis.model.analysisMetaModel.MIDisplay;
+import kieker.analysis.model.analysisMetaModel.MIFilter;
+import kieker.analysis.model.analysisMetaModel.MIInputPort;
+import kieker.analysis.model.analysisMetaModel.MIOutputPort;
+import kieker.analysis.model.analysisMetaModel.MIPlugin;
+import kieker.analysis.model.analysisMetaModel.MIProperty;
+import kieker.analysis.model.analysisMetaModel.MIReader;
+import kieker.analysis.model.analysisMetaModel.MIRepositoryConnector;
+
+/**
+ * This is a container to wrap a single instance of {@link MIPlugin} together with different meta information.
+ * 
+ * @author Nils Christian Ehmke
+ */
+public class PluginContainer implements IComponentContainer {
+
+	private final Map<String, String> propertyDescriptions;
+	private final Map<String, String> displayDescriptions;
+	private final boolean fullyInitialized;
+	private final MIPlugin plugin;
+	private final String description;
+	private final String dependency;
+
+	/**
+	 * Creates a new instance of this class using the given parameters.
+	 * 
+	 * @param plugin
+	 *            The plugin to be stored in this container.
+	 * @param description
+	 *            The description of the plugin.
+	 * @param dependency
+	 *            The dependency description of the plugin.
+	 * @param fullyInitialized
+	 *            A flag to determine whether the plugin has been initialized fully or whether there was an error during the class loading.
+	 * @param propertyDescriptions
+	 *            A map containing the descriptions of the properties of the plugin.
+	 * @param displayDescriptions
+	 *            A map containing the display descriptions of the properties of the plugin.
+	 */
+	public PluginContainer(final MIPlugin plugin, final String description, final String dependency, final boolean fullyInitialized,
+			final Map<String, String> propertyDescriptions, final Map<String, String> displayDescriptions) {
+		this.plugin = plugin;
+		this.description = description;
+		this.dependency = dependency;
+		this.fullyInitialized = fullyInitialized;
+		this.propertyDescriptions = propertyDescriptions;
+		this.displayDescriptions = displayDescriptions;
+	}
+
+	/**
+	 * Delivers the description of the repository.
+	 * 
+	 * @return The human readable description string.
+	 */
+	public String getDescription() {
+		return this.description;
+	}
+
+	/**
+	 * Delivers the dependency description of the repository.
+	 * 
+	 * @return The human readable dependency string.
+	 */
+	public String getDependency() {
+		return this.dependency;
+	}
+
+	/**
+	 * Tells whether the repository has been fully initialized.
+	 * 
+	 * @return true iff the repository has been initialized fully.
+	 */
+	public boolean isFullyInitialized() {
+		return this.fullyInitialized;
+	}
+
+	/**
+	 * Tells whether the instance is a reader or not.
+	 * 
+	 * @return true iff the plugin is a reader
+	 */
+	public boolean isReader() {
+		return this.plugin instanceof MIReader;
+	}
+
+	/**
+	 * Tells whether the instance is a filter or not.
+	 * 
+	 * @return true iff the filter is a reader
+	 */
+	public boolean isFilter() {
+		return this.plugin instanceof MIFilter;
+	}
+
+	/**
+	 * Delivers the description of the given display.
+	 * 
+	 * @param display
+	 *            The name of the display.
+	 * @return The human readable description of the given display.
+	 */
+	public String getDisplayDescription(final String display) {
+		return this.displayDescriptions.get(display);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see kieker.webgui.common.IComponentContainer#getPropertyDescription(java.lang.String)
+	 */
+	@Override
+	public String getPropertyDescription(final String property) {
+		return this.propertyDescriptions.get(property);
+	}
+
+	/**
+	 * Getter for the property {@link PluginContainer#plugin}. <b>DO NOT MODIFIY THIS OBJECT!</b> Use {@link PluginContainer#newInstance(MIAnalysisMetaModelFactory)}
+	 * instead to get a copy.
+	 * 
+	 * @return The current value of the property.
+	 */
+	public MIPlugin getPlugin() {
+		return this.plugin;
+	}
+
+	/**
+	 * Delivers a copy of the plugin instance within this container.
+	 * 
+	 * @param factory
+	 *            The factory to be used to create the copy.
+	 * @return A deep copy of the plugin.
+	 */
+	public MIPlugin newInstance(final MIAnalysisMetaModelFactory factory) {
+		final MIPlugin pluginCopy;
+
+		if (this.plugin instanceof MIReader) {
+			pluginCopy = factory.createReader();
+		} else if (this.plugin instanceof MIFilter) {
+			pluginCopy = factory.createFilter();
+			// Copy the input ports of the plugin instance
+			for (final MIInputPort inputPort : ((MIFilter) this.plugin).getInputPorts()) {
+				final MIInputPort inputPortCopy = factory.createInputPort();
+				inputPortCopy.setName(inputPort.getName());
+				inputPortCopy.setParent((MIFilter) pluginCopy);
+				((MIFilter) pluginCopy).getInputPorts().add(inputPortCopy);
+			}
+		} else {
+			// This should not happen
+			return null;
+		}
+
+		// Copy the output ports of the plugin instance
+		for (final MIOutputPort outputPort : this.plugin.getOutputPorts()) {
+			final MIOutputPort outputPortCopy = factory.createOutputPort();
+			outputPortCopy.setName(outputPort.getName());
+			outputPortCopy.setParent(pluginCopy);
+			pluginCopy.getOutputPorts().add(outputPortCopy);
+		}
+
+		// Copy the repository "ports"
+		for (final MIRepositoryConnector repositoryConnector : this.plugin.getRepositories()) {
+			final MIRepositoryConnector repositoryConnectorCopy = factory.createRepositoryConnector();
+			repositoryConnectorCopy.setName(repositoryConnector.getName());
+			pluginCopy.getRepositories().add(repositoryConnectorCopy);
+		}
+
+		// Copy the displays
+		for (final MIDisplay display : this.plugin.getDisplays()) {
+			final MIDisplay displayCopy = factory.createDisplay();
+			displayCopy.setName(display.getName());
+			displayCopy.setParent(pluginCopy);
+			pluginCopy.getDisplays().add(displayCopy);
+		}
+
+		// Copy the properties
+		for (final MIProperty property : this.plugin.getProperties()) {
+			final MIProperty propertyCopy = factory.createProperty();
+			propertyCopy.setName(property.getName());
+			propertyCopy.setValue(property.getValue());
+			pluginCopy.getProperties().add(propertyCopy);
+		}
+
+		// Copy the remaining attributes
+		pluginCopy.setClassname(this.plugin.getClassname());
+		pluginCopy.setName(this.plugin.getName());
+
+		return pluginCopy;
+	}
+
+}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/RepositoryContainer.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/RepositoryContainer.java
new file mode 100644
index 0000000000000000000000000000000000000000..251d21a943cd7ebc3dac57e6798a997787c6909b
--- /dev/null
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/RepositoryContainer.java
@@ -0,0 +1,135 @@
+/***************************************************************************
+ * Copyright 2012 Kieker Project (http://kieker-monitoring.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ***************************************************************************/
+
+package kieker.webgui.common;
+
+import java.util.Map;
+
+import kieker.analysis.model.analysisMetaModel.MIAnalysisMetaModelFactory;
+import kieker.analysis.model.analysisMetaModel.MIProperty;
+import kieker.analysis.model.analysisMetaModel.MIRepository;
+
+/**
+ * This is a container to wrap a single instance of {@link MIRepository} together with different meta information.
+ * 
+ * @author Nils Christian Ehmke
+ */
+public class RepositoryContainer implements IComponentContainer {
+
+	private final Map<String, String> propertyDescriptions;
+	private final boolean fullyInitialized;
+	private final MIRepository repository;
+	private final String description;
+	private final String dependency;
+
+	/**
+	 * Creates a new instance of this class using the given parameters.
+	 * 
+	 * @param repository
+	 *            The repository to be stored in this container.
+	 * @param description
+	 *            The description of the repository.
+	 * @param dependency
+	 *            The dependency description of the repository.
+	 * @param fullyInitialized
+	 *            A flag to determine whether the repository has been initialized fully or whether there was an error during the class loading.
+	 * @param propertyDescriptions
+	 *            A map containing the descriptions of the properties of the repository.
+	 */
+	public RepositoryContainer(final MIRepository repository, final String description, final String dependency, final boolean fullyInitialized,
+			final Map<String, String> propertyDescriptions) {
+		this.repository = repository;
+		this.description = description;
+		this.dependency = dependency;
+		this.fullyInitialized = fullyInitialized;
+		this.propertyDescriptions = propertyDescriptions;
+	}
+
+	/**
+	 * Delivers the description of the repository.
+	 * 
+	 * @return The human readable description string.
+	 */
+	public String getDescription() {
+		return this.description;
+	}
+
+	/**
+	 * Delivers the dependency description of the repository.
+	 * 
+	 * @return The human readable dependency string.
+	 */
+	public String getDependency() {
+		return this.dependency;
+	}
+
+	/**
+	 * Tells whether the repository has been fully initialized.
+	 * 
+	 * @return true iff the repository has been initialized fully.
+	 */
+	public boolean isFullyInitialized() {
+		return this.fullyInitialized;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see kieker.webgui.common.IComponentContainer#getPropertyDescription(java.lang.String)
+	 */
+	@Override
+	public String getPropertyDescription(final String property) {
+		return this.propertyDescriptions.get(property);
+	}
+
+	/**
+	 * Getter for the property {@link RepositoryContainer#repository}. <b>DO NOT MODIFIY THIS OBJECT!</b> Use
+	 * {@link RepositoryContainer#newInstance(MIAnalysisMetaModelFactory)} instead to get a copy.
+	 * 
+	 * @return The current value of the property.
+	 */
+	public MIRepository getRepository() {
+		return this.repository;
+	}
+
+	/**
+	 * Delivers a copy of the repository instance within this container.
+	 * 
+	 * @param factory
+	 *            The factory to be used to create the copy.
+	 * @return A deep copy of the repository.
+	 */
+	public MIRepository newInstance(final MIAnalysisMetaModelFactory factory) {
+		final MIRepository repositoryCopy;
+
+		repositoryCopy = factory.createRepository();
+
+		// Copy the properties
+		for (final MIProperty property : this.repository.getProperties()) {
+			final MIProperty propertyCopy = factory.createProperty();
+			propertyCopy.setName(property.getName());
+			propertyCopy.setValue(property.getValue());
+			repositoryCopy.getProperties().add(propertyCopy);
+		}
+
+		// Copy the remaining attributes
+		repositoryCopy.setClassname(this.repository.getClassname());
+		repositoryCopy.setName(this.repository.getName());
+
+		return repositoryCopy;
+	}
+
+}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/ViewScope.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ViewScope.java
index af0baa16eeee37b8a180d65aec6f31953d94070f..7962aa9067f69228d0bfe8f0cc4fa7f573e7a9fe 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/ViewScope.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ViewScope.java
@@ -29,6 +29,7 @@ import org.springframework.beans.factory.config.Scope;
  * @author Nils Christian Ehmke
  */
 public class ViewScope implements Scope {
+
 	/**
 	 * Default constructor. <b>Do not use this constructor. This bean is Spring managed.</b>
 	 */
@@ -51,23 +52,44 @@ public class ViewScope implements Scope {
 		}
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.springframework.beans.factory.config.Scope#remove(java.lang.String)
+	 */
 	@Override
 	public Object remove(final String name) {
 		return FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove(name);
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.springframework.beans.factory.config.Scope#getConversationId()
+	 */
 	@Override
 	public String getConversationId() {
 		return null;
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.springframework.beans.factory.config.Scope#registerDestructionCallback(java.lang.String, java.lang.Runnable)
+	 */
 	@Override
 	public void registerDestructionCallback(final String name, final Runnable callback) { // NOPMD (Threads are not used)
 		// Not supported
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.springframework.beans.factory.config.Scope#resolveContextualObject(java.lang.String)
+	 */
 	@Override
 	public Object resolveContextualObject(final String key) {
 		return null;
 	}
+
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/ComponentInitializationException.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/ComponentInitializationException.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7df6fc73281f1a0ff38a4a054913baa7c5c85a4
--- /dev/null
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/ComponentInitializationException.java
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * Copyright 2012 Kieker Project (http://kieker-monitoring.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ***************************************************************************/
+package kieker.webgui.common.exception;
+
+/**
+ * @author Nils Christian Ehmke
+ */
+public class ComponentInitializationException extends AbstractKiekerWebGUIException {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Creates a new instance of this class.
+	 */
+	public ComponentInitializationException() {
+		super();
+	}
+
+	/**
+	 * Creates a new instance of this class using the given parameters.
+	 * 
+	 * @param msg
+	 *            The message used for the exception.
+	 */
+	public ComponentInitializationException(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 cause
+	 *            The cause for the exception.
+	 */
+	public ComponentInitializationException(final String msg, final Throwable cause) {
+		super(msg, cause);
+	}
+}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/InvalidInputSizeException.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/InvalidInputSizeException.java
index 265c5b162a65abab0ce29723cd579ae1b18a0ce7..5a7fef51fcc51ed3c89e0bcdd676315c0b5aa078 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/InvalidInputSizeException.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/InvalidInputSizeException.java
@@ -16,7 +16,6 @@
 
 package kieker.webgui.common.exception;
 
-
 /**
  * An Exception that is thrown when an Array of invalid size is loaded by the GraphFlowLayouter.
  * 
@@ -29,7 +28,32 @@ public class InvalidInputSizeException extends AbstractKiekerWebGUIException {
 
 	private static final long serialVersionUID = 1L;
 
+	/**
+	 * Creates a new instance of this class.
+	 */
 	public InvalidInputSizeException() {
-		super("Input Array has an invalid length!");
+		super();
+	}
+
+	/**
+	 * Creates a new instance of this class using the given parameters.
+	 * 
+	 * @param msg
+	 *            The message used for the exception.
+	 */
+	public InvalidInputSizeException(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 cause
+	 *            The cause for the exception.
+	 */
+	public InvalidInputSizeException(final String msg, final Throwable cause) {
+		super(msg, cause);
 	}
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/UninitializedGraphException.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/UninitializedGraphException.java
index 88b38a0ec289a4b6335439a0d78156af2a44b8f0..3ae0ab8291c6c716b798cb43887152ef20889488 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/UninitializedGraphException.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/UninitializedGraphException.java
@@ -16,7 +16,6 @@
 
 package kieker.webgui.common.exception;
 
-
 /**
  * An Exception that is thrown when trying to connect Edges if a graph has not been
  * loaded by the GraphFlowLayouter.
@@ -27,7 +26,32 @@ public class UninitializedGraphException extends AbstractKiekerWebGUIException {
 
 	private static final long serialVersionUID = 1L;
 
+	/**
+	 * Creates a new instance of this class.
+	 */
 	public UninitializedGraphException() {
-		super("Cannot apply Edges! Graph has not been loaded!");
+		super();
+	}
+
+	/**
+	 * Creates a new instance of this class using the given parameters.
+	 * 
+	 * @param msg
+	 *            The message used for the exception.
+	 */
+	public UninitializedGraphException(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 cause
+	 *            The cause for the exception.
+	 */
+	public UninitializedGraphException(final String msg, final Throwable cause) {
+		super(msg, cause);
 	}
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/layout/GraphFlowLayouter.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/layout/GraphFlowLayouter.java
index 03ed18fa1b379a2295f32f53abd1c2667140013c..44edc884073cb8722801f8e858756131a13631e3 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/layout/GraphFlowLayouter.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/layout/GraphFlowLayouter.java
@@ -58,13 +58,15 @@ public final class GraphFlowLayouter {
 	/**
 	 * Parses a String array, building a graph with nodes and fixed ports.
 	 * 
-	 * @param input
-	 *            The parsed String array
-	 * @return The constructed Graph
+	 * @param positions
+	 *            The node positions.
+	 * @param layoutInformation
+	 *            The necessary information about the graph.
 	 * @throws InvalidInputSizeException
+	 *             If the given input is somehow invalid in size.
 	 */
 	private static void addNodes(final String[] positions, final LayoutInformation layoutInformation) throws InvalidInputSizeException {
-		layoutInformation.graph.getData(KShapeLayout.class).setProperty(LayoutOptions.EDGE_ROUTING, EdgeRouting.ORTHOGONAL);
+		layoutInformation.getGraph().getData(KShapeLayout.class).setProperty(LayoutOptions.EDGE_ROUTING, EdgeRouting.ORTHOGONAL);
 
 		// prepare array of lists
 		List<Object> child;
@@ -97,10 +99,10 @@ public final class GraphFlowLayouter {
 
 			// create Node
 			node = KimlUtil.createInitializedNode();
-			node.setParent(layoutInformation.graph);
+			node.setParent(layoutInformation.getGraph());
 
 			child = new ArrayList<Object>();
-			layoutInformation.children[i] = child;
+			layoutInformation.getChildren()[i] = child;
 			child.add(node);
 
 			// set node dimensions
@@ -156,8 +158,10 @@ public final class GraphFlowLayouter {
 	 * The fourth number must be the index of the target node ArrayList, where
 	 * the target port is located.
 	 * 
-	 * @param input
-	 *            The parsed String array
+	 * @param edgeInfo
+	 *            The single elements for the edges.
+	 * @param layoutInformation
+	 *            The necessary information about the graph.
 	 * @throws UninitializedGraphException
 	 *             If the graph has not yet been initialized.
 	 * @throws InvalidInputSizeException
@@ -165,7 +169,7 @@ public final class GraphFlowLayouter {
 	 */
 	private static void addEdges(final String[] edgeInfo, final LayoutInformation layoutInformation) throws UninitializedGraphException, InvalidInputSizeException {
 		// cannot add edges if no graph was constructed
-		if (layoutInformation.children == null) {
+		if (layoutInformation.getChildren() == null) {
 			throw new UninitializedGraphException();
 		}
 		if ((edgeInfo.length % 4) != 0) {
@@ -186,13 +190,13 @@ public final class GraphFlowLayouter {
 			// read from String
 			sourceID = Integer.parseInt(edgeInfo[e++]);
 			targetID = Integer.parseInt(edgeInfo[e++]);
-			sourcePort = (KPort) layoutInformation.children[sourceID].get(1 + Integer.parseInt(edgeInfo[e++]));
-			targetPort = (KPort) layoutInformation.children[targetID].get(1 + Integer.parseInt(edgeInfo[e++]));
+			sourcePort = (KPort) layoutInformation.getChildren()[sourceID].get(1 + Integer.parseInt(edgeInfo[e++]));
+			targetPort = (KPort) layoutInformation.getChildren()[targetID].get(1 + Integer.parseInt(edgeInfo[e++]));
 
 			// add edge to graph
 			edge = KimlUtil.createInitializedEdge();
-			edge.setSource((KNode) layoutInformation.children[sourceID].get(0));
-			edge.setTarget((KNode) layoutInformation.children[targetID].get(0));
+			edge.setSource((KNode) layoutInformation.getChildren()[sourceID].get(0));
+			edge.setTarget((KNode) layoutInformation.getChildren()[targetID].get(0));
 
 			// set ports of edge
 			edge.setSourcePort(sourcePort);
@@ -200,15 +204,24 @@ public final class GraphFlowLayouter {
 			edge.setTargetPort(targetPort);
 			targetPort.getEdges().add(edge);
 
-			layoutInformation.edges[ea++] = edge;
+			layoutInformation.getEdges()[ea++] = edge;
 		}
 
 	}
 
+	/**
+	 * Assembles the necessary layout information using the given parameters.
+	 * 
+	 * @param nodesStr
+	 *            The string containing the information about the nodes.
+	 * @param edgesStr
+	 *            The string containing the information about the edges.
+	 * @return An object containing the layout information for the graph.
+	 */
 	private static LayoutInformation assembleLayoutInformation(final String nodesStr, final String edgesStr) {
 		final String[] edgeInfo = edgesStr.split(" ");
 		final String[] positions = nodesStr.split(" ");
-		final ArrayList[] children = new ArrayList[positions.length / 2];
+		final List<Object>[] children = new ArrayList[positions.length / 2];
 		final KEdge[] edges = new KEdge[edgeInfo.length / 4];
 		final LayoutInformation layoutInformation = new LayoutInformation(KimlUtil.createInitializedNode(), children, edges);
 
@@ -226,6 +239,11 @@ public final class GraphFlowLayouter {
 	 * @param edges
 	 *            A String containing connection information of edges.
 	 * @return A String of space separated node positions.
+	 * 
+	 * @throws UninitializedGraphException
+	 *             If the graph has not been initialized yet.
+	 * @throws InvalidInputSizeException
+	 *             If the input size is somehow invalid.
 	 */
 	public static String layoutGraph(final String nodes, final String edges) throws UninitializedGraphException, InvalidInputSizeException {
 		final LayoutInformation layoutInformation = GraphFlowLayouter.assembleLayoutInformation(nodes, edges);
@@ -237,7 +255,7 @@ public final class GraphFlowLayouter {
 		final AbstractLayoutProvider layoutProvider = new LayeredLayoutProvider();
 
 		// Perform layout on the created graph
-		layoutProvider.doLayout(layoutInformation.graph, progressMonitor);
+		layoutProvider.doLayout(layoutInformation.getGraph(), progressMonitor);
 
 		// convert layouted graph positions to String
 		final String layoutedGraph = GraphFlowLayouter.getPositions(layoutInformation);
@@ -248,15 +266,15 @@ public final class GraphFlowLayouter {
 	/**
 	 * Reads the (layouted) positions of a constructed KGraph and writes them as integers to a string, seperating each number with a space.
 	 * 
-	 * @param graph
-	 *            The graph with at least one child
-	 * @return The constructed string
+	 * @param layoutInformation
+	 *            The object containing the necessary information about the graph.
+	 * @return The constructed string.
 	 */
 	private static String getPositions(final LayoutInformation layoutInformation) {
 		final StringBuilder sb = new StringBuilder();
 		KShapeLayout layout;
 
-		for (final KNode node : layoutInformation.graph.getChildren()) {
+		for (final KNode node : layoutInformation.getGraph().getChildren()) {
 			layout = node.getData(KShapeLayout.class);
 			final int x = Math.round(layout.getXpos() + (layout.getWidth() / 2));
 			final int y = Math.round(layout.getYpos() + (layout.getHeight() / 2));
@@ -280,7 +298,7 @@ public final class GraphFlowLayouter {
 		final StringBuilder sb = new StringBuilder();
 
 		// iterate edges
-		for (final KEdge edge : layoutInformation.edges) {
+		for (final KEdge edge : layoutInformation.getEdges()) {
 			final KEdgeLayout layout = edge.getData(KEdgeLayout.class);
 			final EList<KPoint> bendPoints = layout.getBendPoints();
 
@@ -299,23 +317,65 @@ public final class GraphFlowLayouter {
 		return sb.toString();
 	}
 
+	/**
+	 * A container for the layout information which will be assembled during the layout process.
+	 * 
+	 * @author Nils Christian Ehmke
+	 */
 	private static class LayoutInformation {
 
-		public final KNode graph;
+		private final KNode graph;
 		/**
 		 * An array containing the child node and the ports from left to right.
 		 */
-		public final List<Object>[] children;
+		private final List<Object>[] children;
 		/**
 		 * An array containing edges. This way we can return edge information in the same order.
 		 */
-		public final KEdge[] edges;
+		private final KEdge[] edges;
 
+		/**
+		 * Creates a new instance of this class.
+		 * 
+		 * @param graph
+		 *            The graph itself.
+		 * @param children
+		 *            The child notes and the ports.
+		 * @param edges
+		 *            The edges of the graph.
+		 */
 		public LayoutInformation(final KNode graph, final List<Object>[] children, final KEdge[] edges) {
 			this.graph = graph;
 			this.children = children;
 			this.edges = edges;
 		}
 
+		/**
+		 * Getter for the property {@link LayoutInformation#graph}.
+		 * 
+		 * @return The current value of the property.
+		 */
+		public KNode getGraph() {
+			return this.graph;
+		}
+
+		/**
+		 * Getter for the property {@link LayoutInformation#children}.
+		 * 
+		 * @return The current value of the property.
+		 */
+		public List<Object>[] getChildren() {
+			return this.children;
+		}
+
+		/**
+		 * Getter for the property {@link LayoutInformation#edges}.
+		 * 
+		 * @return The current value of the property.
+		 */
+		public KEdge[] getEdges() {
+			return this.edges;
+		}
+
 	}
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IProjectDAO.java b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IProjectDAO.java
index 21d5e001d077ffce11fb0f390dce6ec285165440..cb2f98390ffdadd27e8d3456f01cd3f8a6077c00 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IProjectDAO.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IProjectDAO.java
@@ -18,16 +18,14 @@ package kieker.webgui.persistence;
 
 import java.io.File;
 import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
 import java.util.Collection;
 import java.util.List;
 
 import org.springframework.security.access.prepost.PreAuthorize;
 
-import kieker.analysis.model.analysisMetaModel.MIDependency;
 import kieker.analysis.model.analysisMetaModel.MIProject;
 import kieker.webgui.common.ClassAndMethodContainer;
+import kieker.webgui.common.ComponentListContainer;
 import kieker.webgui.common.exception.NewerProjectException;
 import kieker.webgui.common.exception.ProjectAlreadyExistingException;
 import kieker.webgui.common.exception.ProjectNotExistingException;
@@ -193,28 +191,6 @@ public interface IProjectDAO {
 	@PreAuthorize("isAuthenticated()")
 	public abstract Collection<String> listAllProjects();
 
-	/**
-	 * This method can be used to deliver the fully qualified URL of a given dependency for a given project.
-	 * 
-	 * @param lib
-	 *            The library whose URL should be delivered.
-	 * @param project
-	 *            The corresponding project of the library.
-	 * @return The URL to the given library if everything went well.
-	 * @throws MalformedURLException
-	 *             If the URL is for some reason invalid.
-	 */
-	@PreAuthorize("isAuthenticated()")
-	public abstract URL getURL(MIDependency lib, String project) throws MalformedURLException;
-
-	/**
-	 * Delivers the {@link URL}-element pointing to the kieker library.
-	 * 
-	 * @return The kieker library.
-	 */
-	@PreAuthorize("isAuthenticated()")
-	public abstract URL getKiekerURL();
-
 	/**
 	 * Delivers the kax-file for the given project.
 	 * 
@@ -233,8 +209,20 @@ public interface IProjectDAO {
 	 * @param libName
 	 *            The name of the library.
 	 * @return true if and only if the given library has been removed.
+	 * @throws IOException
+	 *             If something went wrong during the reloading of the components.
 	 */
 	@PreAuthorize("hasAnyRole('User', 'Administrator')")
-	public abstract boolean deleteLibrary(String projectName, String libName);
+	public abstract boolean deleteLibrary(String projectName, String libName) throws IOException;
+
+	/**
+	 * Delivers the available components (readers, filters and repositories) for the given project.
+	 * 
+	 * @param project
+	 *            The project whose components should be loaded.
+	 * @return An object containing the available components as model instances.
+	 */
+	@PreAuthorize("isAuthenticated()")
+	public abstract ComponentListContainer getAvailableComponents(String project);
 
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/DerbyUserDAOImpl.java b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/DerbyUserDAOImpl.java
index b64ce0df374631b5438562ad6d888f347bd99cdb..0d61a84a6af00be7b313e2594e10a4b8b45e78e8 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/DerbyUserDAOImpl.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/DerbyUserDAOImpl.java
@@ -23,8 +23,6 @@ import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
 
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
 import javax.sql.DataSource;
 
 import org.springframework.beans.factory.annotation.Autowired;
@@ -52,7 +50,6 @@ public class DerbyUserDAOImpl implements IUserDAO {
 
 	@Autowired
 	private DataSource dataSource;
-	private Connection connection;
 
 	/**
 	 * Default constructor. <b>Do not use this constructor. This bean is Spring managed.</b>
@@ -61,28 +58,6 @@ public class DerbyUserDAOImpl implements IUserDAO {
 		// No code necessary
 	}
 
-	/**
-	 * This method initializes the object. <b>Do not call this method manually. It will only be accessed by Spring.</b>
-	 * 
-	 * @throws SQLException
-	 *             If something went wrong during the initialization.
-	 */
-	@PostConstruct
-	public void initialize() throws SQLException {
-		this.connection = DataSourceUtils.getConnection(this.dataSource);
-	}
-
-	/**
-	 * This method "destroys" the object by closing the connection to the database. <b>Do not call this method manually. It will only be accessed by Spring.</b>
-	 * 
-	 * @throws SQLException
-	 *             If something went wrong during the initialization.
-	 */
-	@PreDestroy
-	public void destroy() throws SQLException {
-		this.connection.close();
-	}
-
 	/*
 	 * (non-Javadoc)
 	 * 
@@ -91,9 +66,10 @@ public class DerbyUserDAOImpl implements IUserDAO {
 	@Override
 	@PreAuthorize("hasRole('Administrator')")
 	public void addUser(final User user) throws DataAccessException {
+		final Connection connection = DataSourceUtils.getConnection(this.dataSource);
 		PreparedStatement userCmd = null;
 		try {
-			userCmd = this.connection.prepareStatement("INSERT INTO Users (name, password, isGuest, isUser, isAdministrator, isEnabled) VALUES (?, ?, ?, ?, ?, ?)");
+			userCmd = connection.prepareStatement("INSERT INTO Users (name, password, isGuest, isUser, isAdministrator, isEnabled) VALUES (?, ?, ?, ?, ?, ?)");
 
 			// Use all properties of the given object
 			userCmd.setString(1, user.getName());
@@ -117,6 +93,12 @@ public class DerbyUserDAOImpl implements IUserDAO {
 					DerbyUserDAOImpl.LOG.error("Could not close prepared statement.", ex);
 				}
 			}
+
+			try {
+				connection.close();
+			} catch (final SQLException ex) {
+				DerbyUserDAOImpl.LOG.error("Could not close connection.", ex);
+			}
 		}
 	}
 
@@ -128,9 +110,10 @@ public class DerbyUserDAOImpl implements IUserDAO {
 	@Override
 	@PreAuthorize("hasRole('Administrator')")
 	public void deleteUser(final User user) throws DataAccessException {
+		final Connection connection = DataSourceUtils.getConnection(this.dataSource);
 		PreparedStatement delCmd = null;
 		try {
-			delCmd = this.connection.prepareStatement("DELETE FROM Users WHERE name=?");
+			delCmd = connection.prepareStatement("DELETE FROM Users WHERE name=?");
 
 			delCmd.setString(1, user.getName());
 
@@ -147,6 +130,12 @@ public class DerbyUserDAOImpl implements IUserDAO {
 					DerbyUserDAOImpl.LOG.error("Could not close prepared statement.", ex);
 				}
 			}
+
+			try {
+				connection.close();
+			} catch (final SQLException ex) {
+				DerbyUserDAOImpl.LOG.error("Could not close connection.", ex);
+			}
 		}
 	}
 
@@ -158,16 +147,16 @@ public class DerbyUserDAOImpl implements IUserDAO {
 	@Override
 	@PreAuthorize("hasRole('Administrator')")
 	public void editUser(final User user) throws DataAccessException {
+		final Connection connection = DataSourceUtils.getConnection(this.dataSource);
 		PreparedStatement updateCmd = null;
 		try {
 			// Choose the right update command, depending on whether the password has to be changed or not
 			if (user.getPassword() == null) {
-				updateCmd = this.connection.prepareStatement("UPDATE Users SET name=?, isGuest=?, isUser=?, isAdministrator=?, isEnabled=? WHERE name=?");
+				updateCmd = connection.prepareStatement("UPDATE Users SET name=?, isGuest=?, isUser=?, isAdministrator=?, isEnabled=? WHERE name=?");
 				updateCmd.setString(6, user.getName());
 			} else {
 				// In this case we have to set the password as well
-				updateCmd = this.connection
-						.prepareStatement("UPDATE Users SET name=?, isGuest=?, isUser=?, isAdministrator=?, isEnabled=?, password=? WHERE name=?");
+				updateCmd = connection.prepareStatement("UPDATE Users SET name=?, isGuest=?, isUser=?, isAdministrator=?, isEnabled=?, password=? WHERE name=?");
 				updateCmd.setString(6, user.getPassword());
 				updateCmd.setString(7, user.getName());
 			}
@@ -192,6 +181,12 @@ public class DerbyUserDAOImpl implements IUserDAO {
 					DerbyUserDAOImpl.LOG.error("Could not close prepared statement.", ex);
 				}
 			}
+
+			try {
+				connection.close();
+			} catch (final SQLException ex) {
+				DerbyUserDAOImpl.LOG.error("Could not close connection.", ex);
+			}
 		}
 	}
 
@@ -203,13 +198,14 @@ public class DerbyUserDAOImpl implements IUserDAO {
 	@Override
 	@PreAuthorize("hasRole('Administrator')")
 	public List<User> getUsers() throws DataAccessException {
+		final Connection connection = DataSourceUtils.getConnection(this.dataSource);
 		final List<User> result = new ArrayList<User>();
 
 		ResultSet queryResult = null;
 		PreparedStatement getQuery = null;
 
 		try {
-			getQuery = this.connection.prepareStatement("SELECT name, isGuest, isUser, isAdministrator, isEnabled FROM Users");
+			getQuery = connection.prepareStatement("SELECT name, isGuest, isUser, isAdministrator, isEnabled FROM Users");
 
 			// Run through all results
 			queryResult = getQuery.executeQuery();
@@ -243,6 +239,12 @@ public class DerbyUserDAOImpl implements IUserDAO {
 					DerbyUserDAOImpl.LOG.error("Could not close prepared statement.", ex);
 				}
 			}
+
+			try {
+				connection.close();
+			} catch (final SQLException ex) {
+				DerbyUserDAOImpl.LOG.error("Could not close connection.", ex);
+			}
 		}
 
 		return result;
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/FSProjectDAOImpl.java b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/FSProjectDAOImpl.java
index a067fffb28c6fe251383fe9abca5822fe53eedc0..d577e0543965f049191b943df0dde75a6e739f54 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/FSProjectDAOImpl.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/FSProjectDAOImpl.java
@@ -22,13 +22,20 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.lang.annotation.Annotation;
 import java.lang.ref.WeakReference;
+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.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -36,6 +43,7 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import javax.annotation.PostConstruct;
 
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Service;
 import org.springframework.util.FileCopyUtils;
@@ -47,20 +55,36 @@ import com.google.common.io.Files;
 
 import kieker.analysis.AnalysisController;
 import kieker.analysis.model.analysisMetaModel.MIAnalysisMetaModelFactory;
-import kieker.analysis.model.analysisMetaModel.MIDependency;
+import kieker.analysis.model.analysisMetaModel.MIDisplay;
+import kieker.analysis.model.analysisMetaModel.MIFilter;
+import kieker.analysis.model.analysisMetaModel.MIInputPort;
+import kieker.analysis.model.analysisMetaModel.MIOutputPort;
+import kieker.analysis.model.analysisMetaModel.MIPlugin;
 import kieker.analysis.model.analysisMetaModel.MIProject;
-import kieker.analysis.model.analysisMetaModel.impl.MAnalysisMetaModelFactory;
+import kieker.analysis.model.analysisMetaModel.MIProperty;
+import kieker.analysis.model.analysisMetaModel.MIRepository;
+import kieker.analysis.model.analysisMetaModel.MIRepositoryConnector;
+import kieker.analysis.plugin.AbstractPlugin;
+import kieker.analysis.plugin.annotation.Property;
+import kieker.analysis.repository.AbstractRepository;
 import kieker.common.logging.Log;
 import kieker.common.logging.LogFactory;
 import kieker.webgui.common.ClassAndMethodContainer;
+import kieker.webgui.common.ComponentListContainer;
+import kieker.webgui.common.PluginContainer;
+import kieker.webgui.common.RepositoryContainer;
+import kieker.webgui.common.exception.ComponentInitializationException;
 import kieker.webgui.common.exception.NewerProjectException;
 import kieker.webgui.common.exception.ProjectAlreadyExistingException;
 import kieker.webgui.common.exception.ProjectNotExistingException;
 import kieker.webgui.persistence.IProjectDAO;
 import kieker.webgui.persistence.impl.util.CloseableURLClassLoader;
+import kieker.webgui.persistence.impl.util.PluginFinder;
 
 import org.primefaces.model.UploadedFile;
 
+import org.eclipse.emf.ecore.EObject;
+
 /**
  * This is an implementation of the {@link IProjectDAO} interface, which uses the file system to store the available projects and everything.
  * 
@@ -71,19 +95,19 @@ public class FSProjectDAOImpl implements IProjectDAO, ReleaseListener {
 
 	private static final Log LOG = LogFactory.getLog(FSProjectDAOImpl.class);
 
+	private static final MIAnalysisMetaModelFactory FACTORY = MIAnalysisMetaModelFactory.eINSTANCE;
+	private static final String KIEKER_LIB = "kieker-1.6_emf.jar";
 	private static final String KAX_EXTENSION = "kax";
 	private static final String LIB_EXTENSION = "jar";
 	private static final String LIB_DIRECTORY = "lib";
 	private static final String ROOT_DIRECTORY = "data";
 
-	/**
-	 * The library for kieker which is contained in the war-file as a resource.
-	 */
-	private static final String KIEKER_LIB = "kieker-1.6_emf.jar";
+	@Autowired
+	private PluginFinder pluginFinder;
 
-	private final MIAnalysisMetaModelFactory factory = new MAnalysisMetaModelFactory();
 	private final Map<CloseableURLClassLoader, WeakReference<Object>> classLoaders = new ConcurrentHashMap<CloseableURLClassLoader, WeakReference<Object>>();
 	private final Map<File, WeakReference<Object>> tempDirs = new ConcurrentHashMap<File, WeakReference<Object>>();
+	private final Map<String, ComponentListContainer> availableComponents = new ConcurrentHashMap<String, ComponentListContainer>();
 
 	/**
 	 * Default constructor. <b>Do not use this constructor. This bean is Spring managed.</b>
@@ -96,12 +120,642 @@ public class FSProjectDAOImpl implements IProjectDAO, ReleaseListener {
 	 * This method initializes the object. <b>Do not call this method manually. It will only be accessed by Spring.</b>
 	 * 
 	 * @throws IOException
-	 *             If the creation of the necessary directories failed.
+	 *             If either the creation of the necessary directories failed or if something went wrong during the initialization of the projects.
 	 */
 	@PostConstruct
 	public void initialize() throws IOException {
 		// Check for the necessary directories and create them if necessary
 		this.checkDir(FSProjectDAOImpl.ROOT_DIRECTORY);
+		// This method call will initialize the available components for all projects which currently exist.
+		this.initializeAvailableComponents();
+	}
+
+	/**
+	 * This method initializes the available components for all projects. This means that this method will run through all projects and load all available plugins,
+	 * filters and repositories from the existing libraries - including Kieker.
+	 * 
+	 * @throws IOException
+	 *             If something went really wrong during the initialization of one of the projects.
+	 */
+	private void initializeAvailableComponents() throws IOException {
+		final Collection<String> projects = this.listAllProjects();
+		// Initialize all available components within all projects
+		for (final String project : projects) {
+			this.initializeAvailableComponents(project);
+		}
+	}
+
+	/**
+	 * This method initializes the available components for the given project. This means that this method will load all available plugins, filters and repositories
+	 * from the existing libraries - including Kieker.
+	 * 
+	 * @param project
+	 *            The name of the project to be initialized.
+	 * @throws IOException
+	 *             If something went really wrong during the initialization of the project.
+	 */
+	private void initializeAvailableComponents(final String project) throws IOException {
+		try {
+			final CloseableURLClassLoader classLoader = (CloseableURLClassLoader) this.getClassLoader(project, this);
+			final ClassAndMethodContainer classAndMethodContainer = new ClassAndMethodContainer(classLoader);
+
+			final List<PluginContainer> readers = new ArrayList<PluginContainer>();
+			final List<PluginContainer> filters = new ArrayList<PluginContainer>();
+			final List<RepositoryContainer> repositories = new ArrayList<RepositoryContainer>();
+
+			// Update the components using all available dependencies
+			final Collection<String> libs = this.listAllLibraries(project);
+			for (final String lib : libs) {
+				this.initializeAvailableComponents(readers, filters, repositories, this.getURL(lib, project), classLoader, classAndMethodContainer);
+			}
+			// Update the components using the Kieker library.
+			this.initializeAvailableComponents(readers, filters, repositories, this.getKiekerURL(), classLoader, classAndMethodContainer);
+
+			// Assemble the final object containing the available components - but make sure that the lists cannot be modified.
+			final ComponentListContainer componentList = new ComponentListContainer(Collections.unmodifiableList(readers), Collections.unmodifiableList(filters),
+					Collections.unmodifiableList(repositories));
+			this.availableComponents.put(project, componentList);
+
+			classLoader.close();
+		} catch (final ProjectNotExistingException ex) {
+			// Technically this should not happen. Log but ignore this exception.
+			FSProjectDAOImpl.LOG.warn("An error occured while initializing the project '" + project + "'.", ex);
+		}
+	}
+
+	/**
+	 * This method initializes the available components for the given library and the given project. It runs through the library and extracts all available readers,
+	 * filters and repositories.
+	 * 
+	 * @param readers
+	 *            The list of readers which will be filled during the extraction process.
+	 * @param filters
+	 *            The list of filters which will be filled during the extraction process.
+	 * @param repositories
+	 *            The list of repositories which will be filled during the extraction process.
+	 * @param lib
+	 *            The url to the library which will be used for the extraction.
+	 * @param classLoader
+	 *            The classloader which will be used to load the classes.
+	 * @param classAndMethodContainer
+	 *            The object containing classes and methods for the extraction process.
+	 * @throws IOException
+	 *             If something went really wrong during the process.
+	 */
+	private void initializeAvailableComponents(final List<PluginContainer> readers, final List<PluginContainer> filters,
+			final List<RepositoryContainer> repositories, final URL lib, final ClassLoader classLoader, final ClassAndMethodContainer classAndMethodContainer) throws
+			IOException {
+		// FInd the available classes within the library
+		final List<Class<AbstractRepository>> repositoryClasses = this.pluginFinder.getAllRepositoriesWithinJar(lib, classLoader, classAndMethodContainer);
+		final List<Class<AbstractPlugin>> pluginClasses = this.pluginFinder.getAllPluginsWithinJar(lib, classLoader, classAndMethodContainer);
+
+		// Convert the repositories into model instances
+		for (final Class<AbstractRepository> repository : repositoryClasses) {
+			if (!(Modifier.isAbstract(repository.getModifiers()) || FSProjectDAOImpl.isProgrammaticOnly(repository, classAndMethodContainer))) {
+				repositories.add(FSProjectDAOImpl.convertRepository(repository, classAndMethodContainer));
+			}
+		}
+
+		// Convert the plugins into model instances
+		for (final Class<AbstractPlugin> plugin : pluginClasses) {
+			if (!(Modifier.isAbstract(plugin.getModifiers()) || FSProjectDAOImpl.isProgrammaticOnly(plugin, classAndMethodContainer))) {
+				final PluginContainer pluginContainer = FSProjectDAOImpl.convertPlugin(plugin, classAndMethodContainer);
+				if (pluginContainer.isReader()) {
+					readers.add(pluginContainer);
+				} else {
+					filters.add(pluginContainer);
+				}
+			}
+		}
+	}
+
+	/**
+	 * This method converts the given class instance into a model instance.
+	 * 
+	 * @param clazz
+	 *            The class to be converted.
+	 * @param classAndMethodContainer
+	 *            The container which will be used for the converting.
+	 * @return An object containing the model instance.
+	 */
+	private static PluginContainer convertPlugin(final Class<AbstractPlugin> clazz, final ClassAndMethodContainer classAndMethodContainer) {
+		final Map<String, String> propertyDescriptions = new HashMap<String, String>();
+		final Map<String, String> displayDescriptions = new HashMap<String, String>();
+		boolean fullyInitialized;
+		String description;
+		String dependency;
+
+		// Create a new instance for the model
+		final MIPlugin plugin;
+		if (classAndMethodContainer.getAbstractReaderPluginClass().isAssignableFrom(clazz)) {
+			plugin = FSProjectDAOImpl.FACTORY.createReader();
+		} else {
+			plugin = FSProjectDAOImpl.FACTORY.createFilter();
+		}
+		plugin.setClassname(clazz.getName());
+		plugin.setName(clazz.getSimpleName());
+
+		// Those are the attributes which can go wrong because of the lazy class loading
+		try {
+			FSProjectDAOImpl.fillProperties(clazz, plugin, classAndMethodContainer, propertyDescriptions);
+			FSProjectDAOImpl.fillPorts(clazz, plugin, classAndMethodContainer);
+			FSProjectDAOImpl.fillDisplays(clazz, plugin, classAndMethodContainer, displayDescriptions);
+			description = FSProjectDAOImpl.getDescription(clazz, classAndMethodContainer);
+			dependency = FSProjectDAOImpl.getDependencies(clazz, classAndMethodContainer);
+
+			fullyInitialized = true;
+		} catch (final ComponentInitializationException ex) {
+			// This exception can occur if (for example) a class is missing. We clear the component as far as possible
+			plugin.getProperties().clear();
+			plugin.getOutputPorts().clear();
+			propertyDescriptions.clear();
+			displayDescriptions.clear();
+			if (plugin instanceof MIFilter) {
+				((MIFilter) plugin).getInputPorts().clear();
+			}
+			description = "";
+			dependency = "";
+
+			fullyInitialized = false;
+
+			FSProjectDAOImpl.LOG.warn("A component with the classname '" + clazz.getCanonicalName() + "' could not be initialized.", ex);
+		}
+
+		// Assemble the resulting instance with everything we could extract and return it
+		return new PluginContainer(plugin, description, dependency, fullyInitialized, Collections.unmodifiableMap(propertyDescriptions),
+				Collections.unmodifiableMap(displayDescriptions));
+	}
+
+	/**
+	 * Tells whether the given class is "programmaticOnly". If there is no annotation which could tell the state of the flag, true will be returned.
+	 * 
+	 * @param clazz
+	 *            The class of the plugin or repository.
+	 * @param classAndMethodContainer
+	 *            The container which will be used for the reflection access.
+	 * @return The state of the programmaticOnly flag of the plugin or repository.
+	 */
+	private static boolean isProgrammaticOnly(final Class<?> clazz, final ClassAndMethodContainer classAndMethodContainer) {
+		boolean result;
+		try {
+			// Get the two potential annotations
+			final Annotation annotationPlugin = clazz.getAnnotation(classAndMethodContainer.getPluginAnnotationClass());
+			final Annotation annotationRepository = clazz.getAnnotation(classAndMethodContainer.getRepositoryAnnotationClass());
+
+			final Method pluginProgOnlyMethod = classAndMethodContainer.getPluginProgrammaticOnlyMethod();
+			final Method repoProgOnlyMethod = classAndMethodContainer.getRepositoryProgrammaticOnlyMethod();
+
+			// Now check which one of them is available
+			if (annotationPlugin == null) {
+				if (annotationRepository == null) {
+					// None. Say it is programmatic only.
+					result = true;
+				} else {
+					result = (Boolean) repoProgOnlyMethod.invoke(annotationRepository);
+				}
+			} else {
+				result = (Boolean) pluginProgOnlyMethod.invoke(annotationPlugin);
+			}
+
+		} catch (final IllegalAccessException ex) {
+			result = true;
+		} catch (final IllegalArgumentException ex) {
+			result = true;
+		} catch (final InvocationTargetException ex) {
+			result = true;
+		} catch (final NoClassDefFoundError ex) {
+			result = true;
+		}
+
+		return result;
+	}
+
+	/**
+	 * This method converts the given class instance into a model instance.
+	 * 
+	 * @param clazz
+	 *            The class to be converted.
+	 * @param classAndMethodContainer
+	 *            The container which will be used for the converting.
+	 * @return An object containing the model instance.
+	 */
+	private static RepositoryContainer convertRepository(final Class<AbstractRepository> clazz, final ClassAndMethodContainer classAndMethodContainer) {
+		final Map<String, String> propertyDescriptions = new HashMap<String, String>();
+		boolean fullyInitialized;
+		String description;
+		String dependency;
+
+		// Create a new instance for the model
+		final MIRepository repository = FSProjectDAOImpl.FACTORY.createRepository();
+
+		repository.setClassname(clazz.getName());
+		repository.setName(clazz.getSimpleName());
+
+		// Those are the attributes which can go wrong because of the lazy class loading
+		try {
+			FSProjectDAOImpl.fillProperties(clazz, repository, classAndMethodContainer, propertyDescriptions);
+			description = FSProjectDAOImpl.getDescription(clazz, classAndMethodContainer);
+			dependency = FSProjectDAOImpl.getDependencies(clazz, classAndMethodContainer);
+
+			fullyInitialized = true;
+		} catch (final ComponentInitializationException ex) {
+			// This exception can occur if (for example) a class is missing. We clear the component as far as possible
+			repository.getProperties().clear();
+			description = "";
+			dependency = "";
+
+			fullyInitialized = false;
+
+			FSProjectDAOImpl.LOG.warn("A component with the classname '" + clazz.getCanonicalName() + "' could not be initialized.", ex);
+		}
+
+		// Assemble the resulting instance with everything we could extract and return it
+		return new RepositoryContainer(repository, description, dependency, fullyInitialized, Collections.unmodifiableMap(propertyDescriptions));
+	}
+
+	/**
+	 * 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 using the java reflection API.
+	 * 
+	 * @param clazz
+	 *            The class whose description should be extracted.
+	 * @param classAndMethodContainer
+	 *            The container which will be used for the reflection invocation.
+	 * @return The description for the class.
+	 * @throws ComponentInitializationException
+	 *             If the description could not be loaded.
+	 */
+	private static String getDescription(final Class<?> clazz, final ClassAndMethodContainer classAndMethodContainer) throws ComponentInitializationException {
+		try {
+			final String description;
+			// Get the two potential annotations
+			final Annotation annotationPlugin = clazz.getAnnotation(classAndMethodContainer.getPluginAnnotationClass());
+			final Annotation annotationRepository = clazz.getAnnotation(classAndMethodContainer.getRepositoryAnnotationClass());
+
+			final Method pluginDescrMethod = classAndMethodContainer.getPluginDescriptionMethod();
+			final Method repoDescrMethod = classAndMethodContainer.getRepositoryDescriptionMethod();
+
+			// Now check which one of them is available
+			if ((annotationPlugin == null) || ((String) pluginDescrMethod.invoke(annotationPlugin)).isEmpty()) {
+				if ((annotationRepository == null) || ((String) repoDescrMethod.invoke(annotationRepository)).isEmpty()) {
+					// None. Deliver a human readable substitute.
+					description = "No description available";
+				} else {
+					description = (String) repoDescrMethod.invoke(annotationRepository);
+				}
+			} else {
+				description = (String) pluginDescrMethod.invoke(annotationPlugin);
+			}
+
+			return description;
+		} catch (final IllegalAccessException ex) {
+			throw new ComponentInitializationException("Could not load the description of the class.", ex);
+		} catch (final IllegalArgumentException ex) {
+			throw new ComponentInitializationException("Could not load the description of the class.", ex);
+		} catch (final InvocationTargetException ex) {
+			throw new ComponentInitializationException("Could not load the description of the class.", ex);
+		} catch (final NoClassDefFoundError ex) {
+			throw new ComponentInitializationException("Could not load the description of the class.", ex);
+		}
+	}
+
+	/**
+	 * Delivers the content of the dependencies-field of the given component (plugin or repository).
+	 * 
+	 * @param clazz
+	 *            The class whose dependencies should be extracted.
+	 * @param classAndMethodContainer
+	 *            The container which will be used for the reflection invocation.
+	 * @return The dependencies for the class.
+	 * @throws ComponentInitializationException
+	 *             If the dependencies could not be loaded.
+	 */
+	private static String getDependencies(final Class<?> clazz, final ClassAndMethodContainer classAndMethodContainer) throws ComponentInitializationException {
+		try {
+			final String description;
+
+			// Get the two potential annotations
+			final Annotation annotationPlugin = clazz.getAnnotation(classAndMethodContainer.getPluginAnnotationClass());
+			final Annotation annotationRepository = clazz.getAnnotation(classAndMethodContainer.getRepositoryAnnotationClass());
+
+			final Method pluginDepMethod = classAndMethodContainer.getPluginDependenciesMethod();
+			final Method repoDepMethod = classAndMethodContainer.getRepositoryDependenciesMethod();
+
+			// Now check which one of them is available
+			if (annotationPlugin == null) {
+				if (annotationRepository == null) {
+					// None. Deliver a human readable substitute.
+					description = "No dependency information available";
+				} else {
+					description = (String) repoDepMethod.invoke(annotationRepository);
+				}
+			} else {
+				description = (String) pluginDepMethod.invoke(annotationPlugin);
+			}
+
+			return description;
+		} catch (final IllegalAccessException ex) {
+			throw new ComponentInitializationException("Could not load the dependencies of the class.", ex);
+		} catch (final IllegalArgumentException ex) {
+			throw new ComponentInitializationException("Could not load the dependencies of the class.", ex);
+		} catch (final InvocationTargetException ex) {
+			throw new ComponentInitializationException("Could not load the dependencies of the class.", ex);
+		} catch (final NoClassDefFoundError ex) {
+			throw new ComponentInitializationException("Could not load the dependencies of the class.", ex);
+		}
+	}
+
+	/**
+	 * 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 component
+	 *            The component to be filled.
+	 * @param classAndMethodContainer
+	 *            The container which will be used for the reflection invocation.
+	 * @param propertyDescriptions
+	 *            The map which will later contain the properties description.
+	 * @throws ComponentInitializationException
+	 *             If the properties could not be loaded.
+	 */
+	private static void fillProperties(final Class<?> clazz, final EObject component, final ClassAndMethodContainer classAndMethodContainer,
+			final Map<String, String> propertyDescriptions) throws ComponentInitializationException {
+		try {
+			// Get the default configuration and use it to initialize the model repository
+			final List<Annotation> properties = FSProjectDAOImpl.getProperties(clazz, classAndMethodContainer);
+
+			for (final Annotation property : properties) {
+				final MIProperty mProperty = FSProjectDAOImpl.FACTORY.createProperty();
+
+				mProperty.setName((String) classAndMethodContainer.getPropertyNameMethod().invoke(property));
+				mProperty.setValue((String) classAndMethodContainer.getPropertyDefaultValueMethod().invoke(property));
+
+				if (component instanceof MIPlugin) {
+					((MIPlugin) component).getProperties().add(mProperty);
+				} else {
+					((MIRepository) component).getProperties().add(mProperty);
+				}
+
+				// Get the description as well
+				final String description = (String) classAndMethodContainer.getPropertyDescriptionMethod().invoke(property);
+				propertyDescriptions.put(mProperty.getName(), description);
+			}
+		} catch (final IllegalAccessException ex) {
+			throw new ComponentInitializationException("Could not load the properties of the class.", ex);
+		} catch (final IllegalArgumentException ex) {
+			throw new ComponentInitializationException("Could not load the properties of the class.", ex);
+		} catch (final InvocationTargetException ex) {
+			throw new ComponentInitializationException("Could not load the properties of the class.", ex);
+		} catch (final NoClassDefFoundError ex) {
+			throw new ComponentInitializationException("Could not load the properties of the class.", ex);
+		}
+	}
+
+	/**
+	 * Delivers the properties of the given class, using the annotations and the java reflection API.
+	 * 
+	 * @param clazz
+	 *            The class whose properties will be delivered.
+	 * @param classAndMethodContainer
+	 *            The container which will be used for the reflection invocation.
+	 * @return A list of properties. It contains instances of {@link Property} - but those from the project class loader.
+	 * @throws InvocationTargetException
+	 *             If something went wrong during the reflection invocation.
+	 * @throws IllegalAccessException
+	 *             If something went wrong during the reflection invocation.
+	 * @throws IllegalArgumentException
+	 *             If something went wrong during the reflection invocation.
+	 */
+	private static List<Annotation> getProperties(final Class<?> clazz, final ClassAndMethodContainer classAndMethodContainer) throws IllegalArgumentException,
+			IllegalAccessException, InvocationTargetException {
+		// Get the two potential annotations
+		final Annotation annotationPlugin = clazz.getAnnotation(classAndMethodContainer.getPluginAnnotationClass());
+		final Annotation annotationRepository = clazz.getAnnotation(classAndMethodContainer.getRepositoryAnnotationClass());
+
+		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[]) classAndMethodContainer.getRepositoryConfigurationMethod().invoke(annotationRepository);
+			}
+		} else {
+			properties = (Annotation[]) classAndMethodContainer.getPluginConfigurationMethod().invoke(annotationPlugin);
+		}
+
+		return Arrays.asList(properties);
+	}
+
+	/**
+	 * 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.
+	 * @param classAndMethodContainer
+	 *            The container which will be used for the reflection invocation.
+	 * @param displayDescriptions
+	 *            The map which will later contain the display description.
+	 * @throws ComponentInitializationException
+	 *             If the properties could not be loaded.
+	 */
+	private static void fillDisplays(final Class<AbstractPlugin> clazz, final MIPlugin plugin, final ClassAndMethodContainer classAndMethodContainer,
+			final Map<String, String> displayDescriptions) throws ComponentInitializationException {
+		try {
+			// Get the displays and convert them into model instances
+			final List<Annotation> displays = FSProjectDAOImpl.getDisplays(clazz, classAndMethodContainer);
+
+			for (final Annotation display : displays) {
+				final MIDisplay mDisplay = FSProjectDAOImpl.FACTORY.createDisplay();
+				mDisplay.setName((String) classAndMethodContainer.getDisplayNameMethod().invoke(display));
+				plugin.getDisplays().add(mDisplay);
+
+				// Get the description as well
+				final String description = (String) classAndMethodContainer.getDisplayDescriptionMethod().invoke(display);
+				displayDescriptions.put(mDisplay.getName(), description);
+			}
+		} catch (final IllegalAccessException ex) {
+			throw new ComponentInitializationException("Could not load the displays of the class.", ex);
+		} catch (final IllegalArgumentException ex) {
+			throw new ComponentInitializationException("Could not load the displays of the class.", ex);
+		} catch (final InvocationTargetException ex) {
+			throw new ComponentInitializationException("Could not load the displays of the class.", ex);
+		} catch (final NoClassDefFoundError ex) {
+			throw new ComponentInitializationException("Could not load the displays of the class.", ex);
+		}
+	}
+
+	/**
+	 * 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.
+	 * @param classAndMethodContainer
+	 *            The container which will be used for the reflection invocation.
+	 * @throws ComponentInitializationException
+	 *             If the properties could not be loaded.
+	 */
+	private static void fillPorts(final Class<AbstractPlugin> clazz, final MIPlugin plugin, final ClassAndMethodContainer classAndMethodContainer) throws
+			ComponentInitializationException {
+		try {
+			// Get the ports
+			final List<Annotation> inputPorts = FSProjectDAOImpl.getInputPorts(clazz, classAndMethodContainer);
+			final List<Annotation> outputPorts = FSProjectDAOImpl.getOutputPorts(clazz, classAndMethodContainer);
+			final List<Annotation> repositoryPorts = FSProjectDAOImpl.getRepositoryPorts(clazz, classAndMethodContainer);
+
+			// Add input ports
+			if (plugin instanceof MIFilter) {
+				for (final Annotation inputPort : inputPorts) {
+					final MIInputPort mInputPort = FSProjectDAOImpl.FACTORY.createInputPort();
+					mInputPort.setName((String) classAndMethodContainer.getInputPortNameMethod().invoke(inputPort));
+					mInputPort.setParent((MIFilter) plugin);
+				}
+			}
+
+			// Add output ports.
+			for (final Annotation outputPort : outputPorts) {
+				final MIOutputPort mOutputPort = FSProjectDAOImpl.FACTORY.createOutputPort();
+				mOutputPort.setName((String) classAndMethodContainer.getOutputPortNameMethod().invoke(outputPort));
+				mOutputPort.setParent(plugin);
+			}
+
+			// Add repository ports.
+			for (final Annotation repositoryPort : repositoryPorts) {
+				final MIRepositoryConnector mConnector = FSProjectDAOImpl.FACTORY.createRepositoryConnector();
+				mConnector.setName((String) classAndMethodContainer.getRepositoryPortNameMethod().invoke(repositoryPort));
+				plugin.getRepositories().add(mConnector);
+			}
+		} catch (final IllegalAccessException ex) {
+			throw new ComponentInitializationException("Could not load the ports of the class.", ex);
+		} catch (final IllegalArgumentException ex) {
+			throw new ComponentInitializationException("Could not load the ports of the class.", ex);
+		} catch (final InvocationTargetException ex) {
+			throw new ComponentInitializationException("Could not load the ports of the class.", ex);
+		} catch (final NoClassDefFoundError ex) {
+			throw new ComponentInitializationException("Could not load the ports of the class.", ex);
+		}
+	}
+
+	/**
+	 * Searches for input ports within the given class and returns them.
+	 * 
+	 * @param clazz
+	 *            The class to be analyzed.
+	 * @param classAndMethodContainer
+	 *            The container which will be used for the reflection invocation.
+	 * @return A list containing the available input ports.
+	 */
+	private static List<Annotation> getInputPorts(final Class<?> clazz, final ClassAndMethodContainer classAndMethodContainer) {
+		final List<Annotation> result = new ArrayList<Annotation>();
+
+		for (final Method method : clazz.getMethods()) {
+			// Get the potential annotation
+			final Annotation annotationPort = method.getAnnotation(classAndMethodContainer.getInputPortAnnotationClass());
+			// Now check whether it is available
+			if (annotationPort != null) {
+				result.add(annotationPort);
+			}
+		}
+
+		return result;
+	}
+
+	/**
+	 * Searches for output ports within the given class and returns them.
+	 * 
+	 * @param clazz
+	 *            The class to be analyzed.
+	 * @param classAndMethodContainer
+	 *            The container which will be used for the reflection invocation.
+	 * @return A list containing the available output ports.
+	 * @throws InvocationTargetException
+	 *             If something went wrong during the reflection invocation.
+	 * @throws IllegalAccessException
+	 *             If something went wrong during the reflection invocation.
+	 * @throws IllegalArgumentException
+	 *             If something went wrong during the reflection invocation.
+	 */
+	private static List<Annotation> getOutputPorts(final Class<?> clazz, final ClassAndMethodContainer classAndMethodContainer) throws IllegalArgumentException,
+			IllegalAccessException, InvocationTargetException {
+		final List<Annotation> result = new ArrayList<Annotation>();
+
+		// Get the potential annotation
+		final Annotation annotationPlugin = clazz.getAnnotation(classAndMethodContainer.getPluginAnnotationClass());
+
+		// Now check whether it is available
+		if (annotationPlugin != null) {
+			for (final Annotation oPort : (Annotation[]) classAndMethodContainer.getPluginOutputPortsMethod().invoke(annotationPlugin)) {
+				result.add(oPort);
+			}
+		}
+
+		return result;
+	}
+
+	/**
+	 * Searches for repository ports within the given class and returns them.
+	 * 
+	 * @param clazz
+	 *            The class to be analyzed.
+	 * @param classAndMethodContainer
+	 *            The container which will be used for the reflection invocation.
+	 * @return A list containing the available repository ports.
+	 * @throws InvocationTargetException
+	 *             If something went wrong during the reflection invocation.
+	 * @throws IllegalAccessException
+	 *             If something went wrong during the reflection invocation.
+	 * @throws IllegalArgumentException
+	 *             If something went wrong during the reflection invocation.
+	 */
+	private static List<Annotation> getRepositoryPorts(final Class<?> clazz, final ClassAndMethodContainer classAndMethodContainer) throws IllegalArgumentException,
+			IllegalAccessException, InvocationTargetException {
+		final List<Annotation> result = new ArrayList<Annotation>();
+
+		// Get the potential annotation
+		final Annotation annotationPlugin = clazz.getAnnotation(classAndMethodContainer.getPluginAnnotationClass());
+
+		// Now check whether it is available
+		if (annotationPlugin != null) {
+			for (final Annotation rPort : (Annotation[]) classAndMethodContainer.getPluginRepositoryPortsMethod().invoke(annotationPlugin)) {
+				result.add(rPort);
+			}
+		}
+
+		return result;
+	}
+
+	/**
+	 * Searches for displays within the given class and returns them.
+	 * 
+	 * @param clazz
+	 *            The class to be analyzed.
+	 * @param classAndMethodContainer
+	 *            The container which will be used for the reflection invocation.
+	 * @return A list containing the available displays.
+	 */
+	private static List<Annotation> getDisplays(final Class<?> clazz, final ClassAndMethodContainer classAndMethodContainer) {
+		final List<Annotation> result = new ArrayList<Annotation>();
+
+		for (final Method method : clazz.getMethods()) {
+			// Get the potential annotation
+			final Annotation display = method.getAnnotation(classAndMethodContainer.getDisplayAnnotationClass());
+			// Now check whether it is available
+			if (display != null) {
+				result.add(display);
+			}
+		}
+
+		return result;
 	}
 
 	/**
@@ -134,7 +788,7 @@ public class FSProjectDAOImpl implements IProjectDAO, ReleaseListener {
 		final File libDir = this.assembleLibDir(projectName);
 
 		// We need an "empty" project in order to save it.
-		final MIProject emptyProject = this.factory.createProject();
+		final MIProject emptyProject = FSProjectDAOImpl.FACTORY.createProject();
 
 		// Make sure that the project doesn't exist already
 		if (projectDir.exists()) {
@@ -146,6 +800,7 @@ public class FSProjectDAOImpl implements IProjectDAO, ReleaseListener {
 			if (projectDir.mkdir() && libDir.mkdir()) {
 				// Try to save the file
 				AnalysisController.saveToFile(projectFile, emptyProject);
+				this.initializeAvailableComponents(projectName);
 			} else {
 				// The directories could not be created
 				throw new IOException("Project-Directories could not be created.");
@@ -322,6 +977,9 @@ public class FSProjectDAOImpl implements IProjectDAO, ReleaseListener {
 
 		// Copy the data - the streams will be closed in this method.
 		FileCopyUtils.copy(in, out);
+
+		// Reload the available components
+		this.initializeAvailableComponents(projectName);
 	}
 
 	/*
@@ -432,6 +1090,12 @@ public class FSProjectDAOImpl implements IProjectDAO, ReleaseListener {
 		return result;
 	}
 
+	@Override
+	@PreAuthorize("isAuthenticated()")
+	public ComponentListContainer getAvailableComponents(final String project) {
+		return this.availableComponents.get(project);
+	}
+
 	/**
 	 * Checks whether a project with the name exists on the file system.
 	 * 
@@ -443,16 +1107,9 @@ public class FSProjectDAOImpl implements IProjectDAO, ReleaseListener {
 		return this.assembleKaxFile(projectName).exists();
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see kieker.webgui.persistence.IProjectDAO#getURL(kieker.analysis.model.analysisMetaModel.MIDependency, java.lang.String)
-	 */
-	@Override
-	@PreAuthorize("isAuthenticated()")
-	public URL getURL(final MIDependency lib, final String project) throws MalformedURLException {
+	private URL getURL(final String lib, final String project) throws MalformedURLException {
 		final File file = new File(FSProjectDAOImpl.ROOT_DIRECTORY + File.separator + project + File.separator + FSProjectDAOImpl.LIB_DIRECTORY + File.separator
-				+ lib.getFilePath());
+				+ lib);
 		return file.toURI().toURL();
 	}
 
@@ -496,20 +1153,22 @@ public class FSProjectDAOImpl implements IProjectDAO, ReleaseListener {
 	 */
 	@Override
 	@PreAuthorize("hasAnyRole('User', 'Administrator')")
-	public boolean deleteLibrary(final String projectName, final String libName) {
+	public boolean deleteLibrary(final String projectName, final String libName) throws IOException {
 		final File libDir = this.assembleLibDir(projectName);
 		final File libFile = new File(libDir, libName);
-		return libFile.delete();
+		final boolean result = libFile.delete();
+		// Reload the available components
+		this.initializeAvailableComponents(projectName);
+
+		return result;
 	}
 
-	/*
-	 * (non-Javadoc)
+	/**
+	 * Delivers an URL pointing to the kieker library within this application.
 	 * 
-	 * @see kieker.webgui.persistence.IProjectDAO#getKiekerURL()
+	 * @return The kieker url.
 	 */
-	@Override
-	@PreAuthorize("isAuthenticated()")
-	public URL getKiekerURL() {
+	private URL getKiekerURL() {
 		return Thread.currentThread().getContextClassLoader().getResource(FSProjectDAOImpl.KIEKER_LIB);
 	}
 
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/PluginFinder.java b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/util/PluginFinder.java
similarity index 99%
rename from Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/PluginFinder.java
rename to Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/util/PluginFinder.java
index 14114b25f355339da753723e53282968bc6d6b26..77b1d731fc083ed72cf7c6e4c93d1080206a069e 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/PluginFinder.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/util/PluginFinder.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  ***************************************************************************/
-package kieker.webgui.service.impl.util;
+package kieker.webgui.persistence.impl.util;
 
 import java.io.IOException;
 import java.net.URL;
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/service/IProjectService.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/IProjectService.java
index c346a35772eaa38ccfa999789e12bc1b1b65b5dd..5b441bd9f9f9f3af8920b110d59e838c9bf14bce 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/service/IProjectService.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/IProjectService.java
@@ -21,15 +21,12 @@ import java.util.Collection;
 import java.util.List;
 
 import kieker.analysis.AnalysisController.STATE;
-import kieker.analysis.model.analysisMetaModel.MIDependency;
 import kieker.analysis.model.analysisMetaModel.MIProject;
-import kieker.analysis.plugin.AbstractPlugin;
-import kieker.analysis.repository.AbstractRepository;
 import kieker.webgui.common.ClassAndMethodContainer;
+import kieker.webgui.common.ComponentListContainer;
 import kieker.webgui.common.exception.AnalysisInitializationException;
 import kieker.webgui.common.exception.AnalysisStateException;
 import kieker.webgui.common.exception.DisplayNotFoundException;
-import kieker.webgui.common.exception.LibraryLoadException;
 import kieker.webgui.common.exception.NewerProjectException;
 import kieker.webgui.common.exception.ProjectAlreadyExistingException;
 import kieker.webgui.common.exception.ProjectNotExistingException;
@@ -181,71 +178,13 @@ public interface IProjectService {
 	public List<String> listAllLibraries(final String projectName) throws ProjectNotExistingException;
 
 	/**
-	 * This method delivers the available classes from the type {@link AbstractRepository} within the given dependency for the given project, using the given
-	 * parameters.
+	 * Delivers the available components (readers, filters and repositories) for the given project.
 	 * 
-	 * @param lib
-	 *            The library to be searched.
 	 * @param project
-	 *            The project for the given library.
-	 * @param classLoader
-	 *            The class loader to be used.
-	 * @param classAndMethodContainer
-	 *            The container with classes and methods to be used.
-	 * @return A list with all repository-classes.
-	 * @throws LibraryLoadException
-	 *             If something went wrong during the loading of the library.
-	 * @throws IOException
-	 */
-	public List<Class<AbstractRepository>> getAllRepositoriesWithinLib(final MIDependency lib, final String project, final ClassLoader classLoader,
-			final ClassAndMethodContainer classAndMethodContainer) throws LibraryLoadException;
-
-	/**
-	 * This method delivers the available classes from the type {@link AbstractPlugin} within the given dependency for the given project, using the given
-	 * parameters.
-	 * 
-	 * @param lib
-	 *            The library to be searched.
-	 * @param project
-	 *            The project for the given library.
-	 * @param classLoader
-	 *            The class loader to be used.
-	 * @param classAndMethodContainer
-	 *            The container with classes and methods to be used.
-	 * @return A list with all plugin-classes.
-	 * @throws LibraryLoadException
-	 *             If something went wrong during the loading of the library.
+	 *            The project whose components should be loaded.
+	 * @return An object containing the available components as model instances.
 	 */
-	public List<Class<AbstractPlugin>> getAllPluginsWithinLib(final MIDependency lib, final String project, final ClassLoader classLoader,
-			final ClassAndMethodContainer classAndMethodContainer) throws LibraryLoadException;
-
-	/**
-	 * This method delivers the available classes from the type {@link AbstractRepository} within the kieker dependency using the given parameters.
-	 * 
-	 * @param classLoader
-	 *            The class loader to be used.
-	 * @param classAndMethodContainer
-	 *            The container with classes and methods to be used.
-	 * @return A list with all repository-classes.
-	 * @throws LibraryLoadException
-	 *             If something went wrong during the loading of the library.
-	 */
-	public List<Class<AbstractRepository>> getAllRepositoriesWithinKiekerLib(final ClassLoader classLoader,
-			final ClassAndMethodContainer classAndMethodContainer) throws LibraryLoadException;
-
-	/**
-	 * This method delivers the available classes from the type {@link AbstractPlugin} within the kieker dependency using the given parameters.
-	 * 
-	 * @param classLoader
-	 *            The class loader to be used.
-	 * @param classAndMethodContainer
-	 *            The container with classes and methods to be used.
-	 * @return A list with all plugin-classes.
-	 * @throws LibraryLoadException
-	 *             If something went wrong during the loading of the library.
-	 */
-	public List<Class<AbstractPlugin>> getAllPluginsWithinKiekerLib(final ClassLoader classLoader, final ClassAndMethodContainer classAndMethodContainer) throws
-			LibraryLoadException;
+	public abstract ComponentListContainer getAvailableComponents(String project);
 
 	/**
 	 * This method lists all available projects on the file system.
@@ -353,6 +292,8 @@ public interface IProjectService {
 	 * @param libName
 	 *            The name of the library.
 	 * @return true if and only if the given library has been removed.
+	 * @throws IOException
+	 *             If something went wrong during the reloading of the components.
 	 */
-	public boolean deleteLibrary(String projectName, String libName);
+	public boolean deleteLibrary(String projectName, String libName) throws IOException;
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/ProjectServiceImpl.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/ProjectServiceImpl.java
index 0bde1b845332c63df4bb36a38e0df4237f7344e7..3ef5078671b796a9b2cf891d6f8489d3e9ee5c73 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/ProjectServiceImpl.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/ProjectServiceImpl.java
@@ -17,7 +17,6 @@
 package kieker.webgui.service.impl;
 
 import java.io.IOException;
-import java.net.MalformedURLException;
 import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
@@ -26,22 +25,18 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import kieker.analysis.AnalysisController.STATE;
-import kieker.analysis.model.analysisMetaModel.MIDependency;
 import kieker.analysis.model.analysisMetaModel.MIProject;
-import kieker.analysis.plugin.AbstractPlugin;
-import kieker.analysis.repository.AbstractRepository;
 import kieker.webgui.common.ClassAndMethodContainer;
+import kieker.webgui.common.ComponentListContainer;
 import kieker.webgui.common.exception.AnalysisInitializationException;
 import kieker.webgui.common.exception.AnalysisStateException;
 import kieker.webgui.common.exception.DisplayNotFoundException;
-import kieker.webgui.common.exception.LibraryLoadException;
 import kieker.webgui.common.exception.NewerProjectException;
 import kieker.webgui.common.exception.ProjectAlreadyExistingException;
 import kieker.webgui.common.exception.ProjectNotExistingException;
 import kieker.webgui.persistence.IProjectDAO;
 import kieker.webgui.service.IProjectService;
 import kieker.webgui.service.impl.util.ACManager;
-import kieker.webgui.service.impl.util.PluginFinder;
 
 import org.primefaces.model.UploadedFile;
 
@@ -59,8 +54,6 @@ public final class ProjectServiceImpl implements IProjectService {
 	private ACManager acManager;
 	@Autowired
 	private IProjectDAO projectDAO;
-	@Autowired
-	private PluginFinder pluginFinder;
 
 	/**
 	 * Default constructor. <b>Do not use this constructor. This bean is Spring managed.</b>
@@ -161,59 +154,11 @@ public final class ProjectServiceImpl implements IProjectService {
 	}
 
 	@Override
-	public List<Class<AbstractRepository>> getAllRepositoriesWithinLib(final MIDependency lib, final String projectName, final ClassLoader classLoader,
-			final ClassAndMethodContainer classAndMethodContainer) throws LibraryLoadException {
-		final Object projectLock = this.getLock(projectName, this.fileSystemLocks);
-
-		synchronized (projectLock) {
-			try {
-				return this.pluginFinder.getAllRepositoriesWithinJar(this.projectDAO.getURL(lib, projectName), classLoader, classAndMethodContainer);
-			} catch (final MalformedURLException ex) {
-				throw new LibraryLoadException("An error occured while loading the library.", ex);
-			} catch (final IOException ex) {
-				throw new LibraryLoadException("An error occured while loading the library.", ex);
-			}
-		}
-	}
-
-	@Override
-	public List<Class<AbstractPlugin>> getAllPluginsWithinLib(final MIDependency lib, final String projectName, final ClassLoader classLoader,
-			final ClassAndMethodContainer classAndMethodContainer) throws LibraryLoadException {
+	public ComponentListContainer getAvailableComponents(final String projectName) {
 		final Object projectLock = this.getLock(projectName, this.fileSystemLocks);
 
 		synchronized (projectLock) {
-			try {
-				return this.pluginFinder.getAllPluginsWithinJar(this.projectDAO.getURL(lib, projectName), classLoader, classAndMethodContainer);
-			} catch (final MalformedURLException ex) {
-				throw new LibraryLoadException("An error occured while loading the library.", ex);
-			} catch (final IOException ex) {
-				throw new LibraryLoadException("An error occured while loading the library.", ex);
-			}
-		}
-	}
-
-	@Override
-	public List<Class<AbstractRepository>> getAllRepositoriesWithinKiekerLib(final ClassLoader classLoader,
-			final ClassAndMethodContainer classAndMethodContainer) throws LibraryLoadException {
-		try {
-			return this.pluginFinder.getAllRepositoriesWithinJar(this.projectDAO.getKiekerURL(), classLoader, classAndMethodContainer);
-
-		} catch (final NullPointerException ex) {
-			throw new LibraryLoadException("An error occured while loading the library.", ex);
-		} catch (final IOException ex) {
-			throw new LibraryLoadException("An error occured while loading the library.", ex);
-		}
-	}
-
-	@Override
-	public List<Class<AbstractPlugin>> getAllPluginsWithinKiekerLib(final ClassLoader classLoader, final ClassAndMethodContainer classAndMethodContainer) throws
-			LibraryLoadException {
-		try {
-			return this.pluginFinder.getAllPluginsWithinJar(this.projectDAO.getKiekerURL(), classLoader, classAndMethodContainer);
-		} catch (final NullPointerException ex) {
-			throw new LibraryLoadException("An error occured while loading the library.", ex);
-		} catch (final IOException ex) {
-			throw new LibraryLoadException("An error occured while loading the library.", ex);
+			return this.projectDAO.getAvailableComponents(projectName);
 		}
 	}
 
@@ -331,7 +276,7 @@ public final class ProjectServiceImpl implements IProjectService {
 	 * @see kieker.webgui.service.IProjectService#deleteLibrary(java.lang.String)
 	 */
 	@Override
-	public boolean deleteLibrary(final String projectName, final String libName) {
+	public boolean deleteLibrary(final String projectName, final String libName) throws IOException {
 		final Object projectLock = this.getLock(projectName, this.fileSystemLocks);
 
 		synchronized (projectLock) {
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorBean.java
index 137e5b80576df4441abedba5b70b7bd2a8517b63..768fbc7cd0a65aade07762d2652fc720ff32683a 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorBean.java
@@ -17,13 +17,8 @@
 package kieker.webgui.web.beans.view;
 
 import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.List;
 
 import javax.faces.application.FacesMessage;
@@ -36,25 +31,21 @@ import org.springframework.stereotype.Component;
 
 import kieker.analysis.model.analysisMetaModel.MIAnalysisMetaModelFactory;
 import kieker.analysis.model.analysisMetaModel.MIDependency;
-import kieker.analysis.model.analysisMetaModel.MIDisplay;
 import kieker.analysis.model.analysisMetaModel.MIFilter;
 import kieker.analysis.model.analysisMetaModel.MIInputPort;
 import kieker.analysis.model.analysisMetaModel.MIOutputPort;
 import kieker.analysis.model.analysisMetaModel.MIPlugin;
 import kieker.analysis.model.analysisMetaModel.MIProject;
-import kieker.analysis.model.analysisMetaModel.MIProperty;
 import kieker.analysis.model.analysisMetaModel.MIReader;
 import kieker.analysis.model.analysisMetaModel.MIRepository;
 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;
-import kieker.webgui.common.ClassAndMethodContainer;
+import kieker.webgui.common.ComponentListContainer;
+import kieker.webgui.common.IComponentContainer;
+import kieker.webgui.common.PluginContainer;
+import kieker.webgui.common.RepositoryContainer;
 import kieker.webgui.common.exception.LibraryLoadException;
 import kieker.webgui.common.exception.NewerProjectException;
 import kieker.webgui.common.exception.ProjectLoadException;
@@ -68,7 +59,6 @@ import org.primefaces.context.RequestContext;
 import org.primefaces.event.FileUploadEvent;
 import org.primefaces.model.UploadedFile;
 
-import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.ecore.EObject;
 
 /**
@@ -76,10 +66,7 @@ import org.eclipse.emf.ecore.EObject;
  * 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 Spring 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.<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.
+ * problems.
  * 
  * @author Nils Christian Ehmke
  */
@@ -87,96 +74,34 @@ import org.eclipse.emf.ecore.EObject;
 @Scope("view")
 // TODO Remove libraries in a clean way
 // TODO Receive libraries once as MIDependencies instead of Strings
-// TODO Use a possibility to reload the classloader explicitly - in this case the manager can close it directly in order to avoid too much memory use
 public final class CurrentAnalysisEditorBean {
-	/**
-	 * 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 field contains the factory, which will be used to create the new components for the project.
-	 */
-	private final MIAnalysisMetaModelFactory factory = new MAnalysisMetaModelFactory();
-	/**
-	 * This field contains the actual model instance, representing the in-memory model of the current view.
-	 */
+	private static final MIAnalysisMetaModelFactory FACTORY = MAnalysisMetaModelFactory.eINSTANCE;
+
+	private ComponentListContainer availableComponents;
+	private EObject selectedComponent;
 	private MIProject 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 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 externally in the
-	 * meanwhile.
-	 */
 	private long timeStamp;
-	/**
-	 * 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<AbstractRepository>> availableRepositories = Collections.synchronizedList(new ArrayList<Class<AbstractRepository>>());
-	/**
-	 * 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<AbstractFilterPlugin>> availableFilters = Collections.synchronizedList(new ArrayList<Class<AbstractFilterPlugin>>());
-	/**
-	 * 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<AbstractReaderPlugin>> availableReaders = Collections.synchronizedList(new ArrayList<Class<AbstractReaderPlugin>>());
-	/**
-	 * This field contains the currently selected component (this can either be a plugin ({@link MIPlugin}) or a repository ({@link MIRepository})).
-	 */
-	private EObject selectedComponent;
+
+	@Autowired
+	private CurrentAnalysisEditorGraphBean currentAnalysisEditorGraphBean;
+	@Autowired
+	private GlobalPropertiesBean globalPropertiesBean;
 	@Autowired
 	private IProjectService projectService;
 	@Autowired
 	private ProjectsBean projectsBean;
 	@Autowired
-	private CurrentAnalysisEditorGraphBean currentAnalysisEditorGraphBean;
-	@Autowired
 	private UserBean userBean;
-	@Autowired
-	private GlobalPropertiesBean globalPropertiesBean;
 
 	/**
 	 * Creates a new instance of this class. <b>Do not call this constructor manually. It will only be accessed by Spring.</b>
 	 */
 	public CurrentAnalysisEditorBean() {
-		// No code necessary
-	}
-
-	/**
-	 * This method delivers the project stored in this bean.
-	 * 
-	 * @return The project for this user.
-	 */
-	public synchronized MIProject getProject() {
-		return this.project;
-	}
-
-	/**
-	 * This method sets the project stored within this bean and returns the new page for the navigation - depending on the given values.
-	 * 
-	 * @param newName
-	 *            The name of the project.
-	 */
-	public synchronized void setProjectName(final String newName) {
-		// Remember the given parameters
-		this.projectName = newName;
+		this.availableComponents = new ComponentListContainer(Collections.<PluginContainer>emptyList(), Collections.<PluginContainer>emptyList(),
+				Collections.<RepositoryContainer>emptyList());
 	}
 
 	/**
@@ -191,13 +116,10 @@ public final class CurrentAnalysisEditorBean {
 				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.initializeModelLibraries();
 				// Load the available readers, filters and repositories
-				this.initializeToolPalette();
+				this.reloadAvailableComponents();
 			}
 		} catch (final ProjectLoadException ex) {
 			CurrentAnalysisEditorBean.LOG.error("An error occured while loading the project.", ex);
@@ -209,115 +131,6 @@ public final class CurrentAnalysisEditorBean {
 		}
 	}
 
-	/**
-	 * 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 synchronized 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.
-	 */
-	private synchronized void initializeToolPalette() {
-		// Clean our tool palette
-		this.availableFilters.clear();
-		this.availableReaders.clear();
-		this.availableRepositories.clear();
-
-		// Run through all libraries and add their content to our lists
-		final Iterator<MIDependency> dependencies = this.project.getDependencies().iterator();
-		while (dependencies.hasNext()) {
-			final MIDependency lib = dependencies.next();
-			try {
-				this.addContentsToToolPalette(lib);
-			} catch (final NullPointerException ex) {
-				dependencies.remove();
-			} catch (final LibraryLoadException ex) {
-				CurrentAnalysisEditorBean.LOG.error("A library could not be loaded correctly.", ex);
-			}
-		}
-		try {
-			// Run also through the kieker library
-			this.addKiekerContentsToToolPalette();
-		} catch (final LibraryLoadException ex) {
-			CurrentAnalysisEditorBean.LOG.error("A library could not be loaded correctly.", ex);
-		}
-	}
-
-	/**
-	 * This method adds the contents (plugins, repositories) within the given dependency to the tool palette.
-	 * 
-	 * @param dependency
-	 *            The dependency which should be added to the palette.
-	 * @throws LibraryLoadException
-	 *             If something went wrong during the loading of the library.
-	 */
-	private synchronized void addContentsToToolPalette(final MIDependency dependency) throws LibraryLoadException {
-		this.addContentsToToolPalette(
-				this.projectService.getAllPluginsWithinLib(dependency, this.projectName, this.classLoader, this.classAndMethodContainer),
-				this.projectService.getAllRepositoriesWithinLib(dependency, this.projectName, this.classLoader, this.classAndMethodContainer));
-	}
-
-	/**
-	 * This method adds the contents (plugins, repositories) within the kieker dependency to the tool palette.
-	 * 
-	 * @throws LibraryLoadException
-	 *             If something went wrong during the loading of the library.
-	 */
-	private synchronized void addKiekerContentsToToolPalette() throws LibraryLoadException {
-		this.addContentsToToolPalette(
-				this.projectService.getAllPluginsWithinKiekerLib(this.classLoader, this.classAndMethodContainer),
-				this.projectService.getAllRepositoriesWithinKiekerLib(this.classLoader, this.classAndMethodContainer));
-	}
-
-	/**
-	 * This method adds all available readers, filters and repositories within the given parameters to the tool palette.
-	 * 
-	 * @param plugins
-	 *            The available readers and filters.
-	 * @param repositories
-	 *            The available repositories.
-	 */
-	@SuppressWarnings("unchecked")
-	private synchronized void addContentsToToolPalette(final List<Class<AbstractPlugin>> plugins, final List<Class<AbstractRepository>> repositories) {
-		// 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())) {
-				// Make also sure that the current repository is not "programmaticOnly"
-				final Annotation annotationRepository = repository.getAnnotation(this.classAndMethodContainer.getRepositoryAnnotationClass());
-				final boolean programmaticOnly = (Boolean) ClassAndMethodContainer.invokeMethod(
-						this.classAndMethodContainer.getRepositoryProgrammaticOnlyMethod(),
-						annotationRepository, false);
-				if (!programmaticOnly) {
-					this.availableRepositories.add(repository);
-				}
-			}
-		}
-
-		for (final Class<?> plugin : plugins) {
-			// Make sure that the current plugin is neither abstract nor "programmaticOnly"
-			final Annotation annotationPlugin = plugin.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass());
-			final boolean programmaticOnly = (Boolean) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPluginProgrammaticOnlyMethod(),
-					annotationPlugin, false);
-			final boolean isAbstract = Modifier.isAbstract(plugin.getModifiers());
-
-			if (!isAbstract && !programmaticOnly) {
-				// 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.
 	 * 
@@ -328,11 +141,10 @@ public final class CurrentAnalysisEditorBean {
 		try {
 			final List<String> libs = this.projectService.listAllLibraries(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
-			// just to valid dependencies (and to all of them).
+			// points just to valid dependencies (and to all of them).
 			this.project.getDependencies().clear();
 			for (final String lib : libs) {
-				final MIDependency dep = this.factory.createDependency();
+				final MIDependency dep = CurrentAnalysisEditorBean.FACTORY.createDependency();
 				dep.setFilePath(lib);
 				this.project.getDependencies().add(dep);
 			}
@@ -342,329 +154,130 @@ public final class CurrentAnalysisEditorBean {
 	}
 
 	/**
-	 * This method reloads the class loader. In other words: The class loader will always be able to load classes from the jar-files within the lib-folder of the
-	 * project.
+	 * This method is the handler for the file upload. It tries to upload the given file and informs the user via the growl-component.
 	 * 
-	 * @throws ProjectLoadException
-	 *             If something went wrong.
+	 * @param event
+	 *            The upload event.
 	 */
-	private synchronized void reloadClassLoader() throws ProjectLoadException {
+	public synchronized void handleFileUpload(final FileUploadEvent event) {
+		// Get the file from the event
+		final UploadedFile file = event.getFile();
+
 		try {
-			this.classLoader = this.projectService.getClassLoader(this.projectName, this); // NOPMD (ClassLoader)
-		} catch (final NullPointerException ex) {
-			throw new ProjectLoadException("Invalid class loader.", ex);
+			// Use the file system manager to upload the new file
+			final MIDependency lib;
+			this.projectService.uploadLibrary(file, this.projectName);
+			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_INFO, this.globalPropertiesBean.getMsgLibraryUploaded());
+			// As it seem to have worked, we can add the library to our model.
+			lib = CurrentAnalysisEditorBean.FACTORY.createDependency();
+			lib.setFilePath(file.getFileName());
+			this.project.getDependencies().add(lib);
+			// Update our class loader and the available plugins & repositories
+
+			// We have to reinitialize the tool palette completely! This is necessary as some of the already existing classes could need the newly loaded classes.
+			this.reloadAvailableComponents();
 		} catch (final IOException ex) {
-			throw new ProjectLoadException("Could not load classes.", ex);
+			CurrentAnalysisEditorBean.LOG.error("An error occured while uploading the library.", ex);
+			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgLibraryUploadingException());
+		} catch (final ProjectLoadException ex) {
+			CurrentAnalysisEditorBean.LOG.error("An error occured while uploading the library.", ex);
+			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgLibraryUploadingException());
 		} catch (final ProjectNotExistingException ex) {
-			throw new ProjectLoadException("Project does not exist.", ex);
-		}
-	}
-
-	/**
-	 * This method sets the time stamp to the current system time.
-	 */
-	public synchronized void resetTimeStamp() {
-		this.timeStamp = System.currentTimeMillis();
-	}
-
-	/**
-	 * This method delivers the project name stored in this bean.
-	 * 
-	 * @return The project name for this user.
-	 */
-	public synchronized String getProjectName() {
-		return this.projectName;
-	}
-
-	/**
-	 * This method delivers the current time stamp.
-	 * 
-	 * @return The time stamp for this user.
-	 */
-	public synchronized long getTimeStamp() {
-		return this.timeStamp;
-	}
-
-	/**
-	 * 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 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 synchronized String getDescription(final Class<?> clazz) {
-		final String description;
-		// 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.
-				description = "No description available";
-			} else {
-				description = (String) ClassAndMethodContainer.invokeMethod(repoDescrMethod, annotationRepository, "No description available");
-			}
-		} else {
-			description = (String) ClassAndMethodContainer.invokeMethod(pluginDescrMethod, annotationPlugin, "No description available");
+			CurrentAnalysisEditorBean.LOG.error("Project does not exist.", ex);
+			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectNotExistingException());
+		} catch (final LibraryLoadException ex) {
+			CurrentAnalysisEditorBean.LOG.error("An error occured while uploading the library.", ex);
+			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgLibraryUploadingException());
 		}
-
-		return description;
 	}
 
 	/**
-	 * Delivers the content of the dependencies-field of the given component (plugin or repository).
+	 * Removes the library with the given name and reloads the classes and the classloader. Furthermore the tool palette will be reinitalized.
 	 * 
-	 * @param clazz
-	 *            The class whose dependencies should be extracted.
-	 * @return The dependencies for the class or a substitute if none is available. This is in either case human readable.
+	 * @param name
+	 *            The name of the library to be removed.
 	 */
-	public synchronized String getDependencies(final Class<?> clazz) {
-		final String description;
-
-		// Get the two potential annotations
-		final Annotation annotationPlugin = clazz.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass());
-		final Annotation annotationRepository = clazz.getAnnotation(this.classAndMethodContainer.getRepositoryAnnotationClass());
-
-		final Method pluginDepMethod = this.classAndMethodContainer.getPluginDependenciesMethod();
-		final Method repoDepMethod = this.classAndMethodContainer.getRepositoryDependenciesMethod();
-
-		// Now check which one of them is available
-		if (annotationPlugin == null) {
-			if (annotationRepository == null) {
-				// None. Deliver a human readable substitute.
-				description = "No dependency information available";
-			} else {
-				description = (String) ClassAndMethodContainer.invokeMethod(repoDepMethod, annotationRepository, "No dependency information available");
+	public synchronized void deleteLibrary(final String name) {
+		try {
+			if (this.projectService.deleteLibrary(this.projectName, name)) {
+				// We have to reinitialize the tool palette completely! This is necessary as some of the already existing classes could need the newly loaded
+				// classes.
+				this.reloadAvailableComponents();
 			}
-		} else {
-			description = (String) ClassAndMethodContainer.invokeMethod(pluginDepMethod, annotationPlugin, "No dependency information available");
+		} catch (final IOException ex) {
+			CurrentAnalysisEditorBean.LOG.error("An error occured while removing the library.", ex);
+			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while removing the library.");
 		}
-
-		return description;
 	}
 
 	/**
-	 * Delivers the description of the property of the given component (plugin or repository).
-	 * 
-	 * @param component
-	 *            The component whose property description should be delivered.
-	 * @param propertyName
-	 *            The name of the property in question.
-	 * @return The description of the property.
+	 * This method loads the list of available readers, filters and repositories, using the current libraries within the model.
 	 */
-	public synchronized String getDescription(final EObject component, final String propertyName) {
-		try {
-			final String className;
-			if (component instanceof MIPlugin) {
-				className = ((MIPlugin) component).getClassname();
-			} else {
-				if (component instanceof MIRepository) {
-					className = ((MIRepository) component).getClassname();
-				} else {
-					// Unknown type
-					return "N/A";
-				}
-			}
-			final Class<?> clazz = this.classLoader.loadClass(className);
-			final List<Annotation> properties = this.getProperties(clazz);
-			// Run through all the properties and find the correct one
-			for (final Annotation property : properties) {
-				final String name = (String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPropertyNameMethod(), property, "");
-				if (propertyName.equals(name)) {
-					return (String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPropertyDescriptionMethod(), property, "");
-				}
-			}
-		} catch (final ClassNotFoundException ex) {
-			CurrentAnalysisEditorBean.LOG.warn("Could not find class.", ex);
-		}
-		// If we are here we found nothing
-		return "N/A";
+	private synchronized void reloadAvailableComponents() {
+		this.availableComponents = this.projectService.getAvailableComponents(this.projectName);
 	}
 
 	/**
-	 * Delivers the properties of the given class, using the annotations and the java reflection API.
+	 * This method delivers the project stored in this bean.
 	 * 
-	 * @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.
+	 * @return The project for this user.
 	 */
-	public synchronized List<Annotation> getProperties(final Class<?> clazz) {
-		// Get the two potential annotations
-		final Annotation annotationPlugin = clazz.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass());
-		final Annotation annotationRepository = clazz.getAnnotation(this.classAndMethodContainer.getRepositoryAnnotationClass());
-
-		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[]) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getRepositoryConfigurationMethod(),
-						annotationRepository, new Property[0]);
-			}
-		} else {
-			properties = (Annotation[]) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPluginConfigurationMethod(),
-					annotationPlugin, new Property[0]);
-		}
-
-		return Arrays.asList(properties);
+	public synchronized MIProject getProject() {
+		return this.project;
 	}
 
 	/**
-	 * Searches for input ports within the given class and returns them.
+	 * This method sets the project stored within this bean and returns the new page for the navigation - depending on the given values.
 	 * 
-	 * @param clazz
-	 *            The class to be analyzed.
-	 * @return A list containing the available input ports.
+	 * @param newName
+	 *            The name of the project.
 	 */
-	public synchronized List<Annotation> getInputPorts(final Class<?> clazz) {
-		final List<Annotation> result = new ArrayList<Annotation>();
-
-		for (final Method method : clazz.getMethods()) {
-			// Get the potential annotation
-			final Annotation annotationPort = method.getAnnotation(this.classAndMethodContainer.getInputPortAnnotationClass());
-			// Now check whether it is available
-			if (annotationPort != null) {
-				result.add(annotationPort);
-			}
-		}
-
-		return result;
+	public synchronized void setProjectName(final String newName) {
+		// Remember the given parameters
+		this.projectName = newName;
 	}
 
 	/**
-	 * Searches for output ports within the given class and returns them.
+	 * This method delivers the project name stored in this bean.
 	 * 
-	 * @param clazz
-	 *            The class to be analyzed.
-	 * @return A list containing the available output ports.
+	 * @return The project name for this user.
 	 */
-	public synchronized List<Annotation> getOutputPorts(final Class<?> clazz) {
-		final List<Annotation> result = new ArrayList<Annotation>();
-
-		// 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[]) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPluginOutputPortsMethod(),
-					annotationPlugin, new Annotation[0])) {
-				result.add(oPort);
-			}
-		}
-
-		return result;
+	public synchronized String getProjectName() {
+		return this.projectName;
 	}
 
 	/**
-	 * Searches for repository ports within the given class and returns them.
+	 * This method delivers the available components for the current project. The delivered components are never abstract or programmaticOnly.
 	 * 
-	 * @param clazz
-	 *            The class to be analyzed.
-	 * @return A list containing the available repository ports.
+	 * @return A list with all components.
 	 */
-	public synchronized List<Annotation> getRepositoryPorts(final Class<?> clazz) {
-		final List<Annotation> result = new ArrayList<Annotation>();
-
-		// 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);
-			}
-		}
-
-		return result;
+	public synchronized ComponentListContainer getAvailableComponents() {
+		return this.availableComponents;
 	}
 
 	/**
-	 * Searches for displays within the given class and returns them.
-	 * 
-	 * @param clazz
-	 *            The class to be analyzed.
-	 * @return A list containing the available displays.
+	 * This method sets the time stamp to the current system time.
 	 */
-	public synchronized List<Annotation> getDisplays(final Class<?> clazz) {
-		final List<Annotation> result = new ArrayList<Annotation>();
-
-		for (final Method method : clazz.getMethods()) {
-			// Get the potential annotation
-			final Annotation display = method.getAnnotation(this.classAndMethodContainer.getDisplayAnnotationClass());
-			// Now check whether it is available
-			if (display != null) {
-				result.add(display);
-			}
-		}
-
-		return result;
+	public synchronized void resetTimeStamp() {
+		this.timeStamp = System.currentTimeMillis();
 	}
 
 	/**
-	 * This method is the handler for the file upload. It tries to upload the given file and informs the user via the growl-component.
+	 * This method delivers the current time stamp.
 	 * 
-	 * @param event
-	 *            The upload event.
+	 * @return The time stamp for this user.
 	 */
-	public synchronized void handleFileUpload(final FileUploadEvent event) {
-		// Get the file from the event
-		final UploadedFile file = event.getFile();
-
-		try {
-			// Use the file system manager to upload the new file
-			final MIDependency lib;
-			this.projectService.uploadLibrary(file, this.projectName);
-			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_INFO, this.globalPropertiesBean.getMsgLibraryUploaded());
-			// As it seem to have worked, we can add the library to our model.
-			lib = this.factory.createDependency();
-			lib.setFilePath(file.getFileName());
-			this.project.getDependencies().add(lib);
-			// Update our class loader and the available plugins & repositories
-			this.reloadClassLoader();
-			this.reloadClassesAndMethods();
-
-			// We have to reinitialize the tool palette completely! This is necessary as some of the already existing classes could need the newly loaded classes.
-			this.initializeToolPalette();
-		} catch (final IOException ex) {
-			CurrentAnalysisEditorBean.LOG.error("An error occured while uploading the library.", ex);
-			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgLibraryUploadingException());
-		} catch (final ProjectLoadException ex) {
-			CurrentAnalysisEditorBean.LOG.error("An error occured while uploading the library.", ex);
-			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgLibraryUploadingException());
-		} catch (final ProjectNotExistingException ex) {
-			CurrentAnalysisEditorBean.LOG.error("Project does not exist.", ex);
-			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectNotExistingException());
-		} catch (final LibraryLoadException ex) {
-			CurrentAnalysisEditorBean.LOG.error("An error occured while uploading the library.", ex);
-			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgLibraryUploadingException());
-		}
+	public synchronized long getTimeStamp() {
+		return this.timeStamp;
 	}
 
 	/**
-	 * Removes the library with the given name and reloads the classes and the classloader. Furthermore the tool palette will be reinitalized.
+	 * This method delivers the currently selected plugin (or the currently selected repository). If nothing has been selected, null will be returned.
 	 * 
-	 * @param name
-	 *            The name of the library to be removed.
+	 * @return The currently selected plugin or repository.
 	 */
-	public synchronized void deleteLibrary(final String name) {
-		if (this.projectService.deleteLibrary(this.projectName, name)) {
-			// Update our class loader and the available plugins & repositories
-			this.reloadClassLoader();
-			this.reloadClassesAndMethods();
-
-			// We have to reinitialize the tool palette completely! This is necessary as some of the already existing classes could need the newly loaded classes.
-			this.initializeToolPalette();
-		}
+	public synchronized EObject getSelectedPlugin() {
+		return this.selectedComponent;
 	}
 
 	/**
@@ -688,33 +301,6 @@ public final class CurrentAnalysisEditorBean {
 		return new ArrayList<String>();
 	}
 
-	/**
-	 * This method delivers the available reader-plugins for the current main project. The delivered plugins are never abstract.
-	 * 
-	 * @return A list with all readers.
-	 */
-	public synchronized List<Class<AbstractReaderPlugin>> getAvailableReaders() {
-		return this.availableReaders;
-	}
-
-	/**
-	 * This method delivers the available filter-plugins for the current main project. The delivered plugins are never abstract.
-	 * 
-	 * @return A list with all filter.
-	 */
-	public synchronized List<Class<AbstractFilterPlugin>> getAvailableFilters() {
-		return this.availableFilters;
-	}
-
-	/**
-	 * This method delivers the available repositories for the current main project. The delivered repositories are never abstract.
-	 * 
-	 * @return A list with all repositories.
-	 */
-	public synchronized List<Class<AbstractRepository>> getAvailableRepositories() {
-		return this.availableRepositories;
-	}
-
 	/**
 	 * This method tries to save the current project and informs the user about success or fail.
 	 * 
@@ -742,163 +328,39 @@ public final class CurrentAnalysisEditorBean {
 	}
 
 	/**
-	 * 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.
-	 */
-	private synchronized void fillDisplays(final Class<AbstractPlugin> clazz, final MIPlugin plugin) {
-		// 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 extract the list of ports from the given class (using the annotations) and
-	 * to convert them into model instances.
+	 * This method adds a new repository to the current model, using the given instance of {@code RepositoryContainer} for it.
 	 * 
-	 * @param clazz
-	 *            The class to be used as a base.
-	 * @param plugin
-	 *            The plugin to be filled.
+	 * @param container
+	 *            The container which delivers the copy of the repository.
 	 */
-	private synchronized void fillPorts(final Class<AbstractPlugin> clazz, final MIPlugin 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);
-			}
-		}
+	public synchronized void addRepository(final RepositoryContainer container) {
+		// Create a new instance for the model
+		final MIRepository repository = container.newInstance(CurrentAnalysisEditorBean.FACTORY);
 
-		// 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);
-		}
-
-		// 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 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 component
-	 *            The component to be filled.
-	 */
-	private synchronized 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();
-
-			mProperty.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPropertyNameMethod(), property, "N/A"));
-			mProperty.setValue((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPropertyDefaultValueMethod(), property, "N/A"));
-
-			if (component instanceof MIPlugin) {
-				((MIPlugin) component).getProperties().add(mProperty);
-			} else {
-				((MIRepository) component).getProperties().add(mProperty);
-			}
-		}
-
-	}
-
-	/**
-	 * This method adds a new repository to the current model, using the given instance of {@code Class} for it.
-	 * 
-	 * @param clazz
-	 *            The class of the repository to be added.
-	 */
-	public synchronized void addRepository(final Class<AbstractRepository> clazz) {
-		try {
-			// Create a new instance for the model
-			final MIRepository repository = this.factory.createRepository();
-			repository.setClassname(clazz.getName());
-			repository.setName(clazz.getSimpleName());
-
-			this.fillProperties(clazz, repository);
-			// Add it to the project - and to the graph
-			this.project.getRepositories().add(repository);
-			this.currentAnalysisEditorGraphBean.addRepository(repository);
-			this.currentAnalysisEditorGraphBean.refreshGraph();
-		} catch (final NoClassDefFoundError ex) {
-			// This exception can occur if (for example) a class is missing
-			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgRepositoryCreationException());
-			CurrentAnalysisEditorBean.LOG.error("An error occured during the creation of the repository. Check the dependencies.", ex);
-		}
+		// Add it to the project - and to the graph
+		this.project.getRepositories().add(repository);
+		this.currentAnalysisEditorGraphBean.addRepository(repository);
+		this.currentAnalysisEditorGraphBean.refreshGraph();
 	}
 
 	/**
-	 * This method adds a new plugin to the current model, using the given instance of {@code Class} for it.
+	 * This method adds a new plugin to the current model, using the given instance of {@code PluginContainer} for it.
 	 * 
-	 * @param clazz
-	 *            The class of the plugin to be added. This can be both, a filter or a reader.
+	 * @param container
+	 *            The container which delivers the copy of the plugin.
 	 */
-	public synchronized void addPlugin(final Class<AbstractPlugin> clazz) {
-		try {
-			// Create a new instance for the model
-			final MIPlugin plugin;
-			if (this.classAndMethodContainer.getAbstractReaderPluginClass().isAssignableFrom(clazz)) {
-				plugin = this.factory.createReader();
-			} else {
-				plugin = this.factory.createFilter();
-			}
-			plugin.setClassname(clazz.getName());
-			plugin.setName(clazz.getSimpleName());
-
-			this.fillProperties(clazz, plugin);
-			this.fillPorts(clazz, plugin);
-			this.fillDisplays(clazz, plugin);
+	public synchronized void addPlugin(final PluginContainer container) {
+		// Create a new instance for the model
+		final MIPlugin plugin = container.newInstance(CurrentAnalysisEditorBean.FACTORY);
 
-			// 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();
-		} catch (final NoClassDefFoundError ex) {
-			// This exception can occur if (for example) a class is missing
-			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgPluginCreationException());
-			CurrentAnalysisEditorBean.LOG.error("An error occured during the creation of the plugin. Check the dependencies.", ex);
+		// Add it to the project - and to the graph
+		this.project.getPlugins().add(plugin);
+		if (plugin instanceof MIReader) {
+			this.currentAnalysisEditorGraphBean.addReader((MIReader) plugin);
+		} else {
+			this.currentAnalysisEditorGraphBean.addFilter((MIFilter) plugin);
 		}
-	}
-
-	/**
-	 * This method delivers the currently selected plugin (or the currently selected repository). If nothing has been selected, null will be returned.
-	 * 
-	 * @return The currently selected plugin or repository.
-	 */
-	public synchronized EObject getSelectedPlugin() {
-		return this.selectedComponent;
+		this.currentAnalysisEditorGraphBean.refreshGraph();
 	}
 
 	/**
@@ -926,48 +388,51 @@ public final class CurrentAnalysisEditorBean {
 	}
 
 	/**
-	 * This method delivers a list containing all available filters within the model instance. It is the same as calling project.getPlugins() but instead this method
-	 * returns only instances of {@link MIFilter}.
+	 * Delivers a human readable description of the given property.
 	 * 
-	 * @return A list with the available filters.
-	 */
-	public synchronized List<MIPlugin> getFilters() {
-		final EList<MIPlugin> plugins = this.project.getPlugins();
-		final List<MIPlugin> filter = new ArrayList<MIPlugin>();
-
-		for (final MIPlugin plugin : plugins) {
-			if (plugin instanceof MIFilter) {
-				filter.add(plugin);
+	 * @param component
+	 *            The parent of the property.
+	 * @param property
+	 *            The property name.
+	 * @return A human readable description and a substitution if there is no description.
+	 */
+	public synchronized String getDescription(final EObject component, final String property) {
+		IComponentContainer container = null;
+
+		// Find the container which contains the component
+		if (component instanceof MIReader) {
+			final String className = ((MIReader) component).getClassname();
+			for (final PluginContainer reader : this.availableComponents.getReaders()) {
+				if (reader.getPlugin().getClassname().equals(className)) {
+					container = reader;
+					break;
+				}
 			}
-		}
-
-		return filter;
-	}
-
-	/**
-	 * Delivers all available repositories.
-	 * 
-	 * @return A list with all repositories within the model.
-	 */
-	public synchronized EList<MIRepository> getRepositories() {
-		return this.project.getRepositories();
-	}
-
-	/**
-	 * Delivers the name of the currently selected plugin/repository. This is only necessary for the correct renaming of the components.
-	 * 
-	 * @return The name of the plugin/repository.
-	 */
-	public synchronized String getCurrentPluginName() {
-		if (this.selectedComponent != null) {
-			if (this.selectedComponent instanceof MIPlugin) {
-				return ((MIPlugin) this.selectedComponent).getName();
-			} else {
-				return ((MIRepository) this.selectedComponent).getName();
+		} else if (component instanceof MIFilter) {
+			final String className = ((MIFilter) component).getClassname();
+			for (final PluginContainer filter : this.availableComponents.getFilters()) {
+				if (filter.getPlugin().getClassname().equals(className)) {
+					container = filter;
+					break;
+				}
 			}
 		} else {
-			return "";
+			final String className = ((MIRepository) component).getClassname();
+			for (final RepositoryContainer repository : this.availableComponents.getRepositories()) {
+				if (repository.getRepository().getClassname().equals(className)) {
+					container = repository;
+					break;
+				}
+			}
 		}
+
+		// Extract the description
+		if (container != null) {
+			return container.getPropertyDescription(property);
+		}
+
+		// Nothing found
+		return "No description available.";
 	}
 
 	/**
@@ -1091,7 +556,7 @@ public final class CurrentAnalysisEditorBean {
 			}
 		}
 
-		// Unselect the currently selected node if it is the one which has just been removed
+		// Deselect the currently selected node if it is the one which has just been removed
 		if (this.selectedComponent == node) {
 			this.selectedComponent = null; // NOPMD
 		}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitBean.java
index 7fbcc0684f8018f0e15fa1d53568771b5851f530..d16f63c374f6519bb48d86d3cd140b8bcfeaca86 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitBean.java
@@ -16,7 +16,6 @@
 
 package kieker.webgui.web.beans.view;
 
-import java.io.IOException;
 import java.util.List;
 
 import javax.faces.application.Application;
@@ -179,17 +178,12 @@ public final class CurrentCockpitBean {
 				this.project = this.projectsBean.openProject(this.projectName);
 
 				if (this.project != null) {
-					final ClassLoader classLoader = this.projectService.getClassLoader(this.projectName, this); // NOPMD (ClassLoader)
-					this.classAndMethodContainer = new ClassAndMethodContainer(classLoader);
 					this.fillDashboard();
 				}
 			}
 		} catch (final ProjectNotExistingException ex) {
 			CurrentCockpitBean.LOG.error("An error occured while loading the project.", ex);
 			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project.");
-		} catch (final IOException ex) {
-			CurrentCockpitBean.LOG.error("An error occured while loading the project.", ex);
-			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project.");
 		} catch (final NullPointerException ex) {
 			// This exception occurs, when the projectsBean has not been initialized
 			CurrentCockpitBean.LOG.error("An error occured while loading the project.", ex);
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java
index 41a019cc0d434b5d7c64326170389dffa5104491..ae1e9aa34dcf6de4842456af73e1420d0dc1ed0b 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java
@@ -17,9 +17,7 @@
 package kieker.webgui.web.beans.view;
 
 import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import javax.faces.application.Application;
@@ -33,17 +31,17 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 
-import kieker.analysis.display.annotation.Display;
 import kieker.analysis.model.analysisMetaModel.MIAnalysisMetaModelFactory;
 import kieker.analysis.model.analysisMetaModel.MIDisplay;
 import kieker.analysis.model.analysisMetaModel.MIDisplayConnector;
 import kieker.analysis.model.analysisMetaModel.MIProject;
 import kieker.analysis.model.analysisMetaModel.MIView;
 import kieker.analysis.model.analysisMetaModel.impl.MAnalysisMetaModelFactory;
-import kieker.analysis.plugin.AbstractPlugin;
 import kieker.common.logging.Log;
 import kieker.common.logging.LogFactory;
-import kieker.webgui.common.ClassAndMethodContainer;
+import kieker.webgui.common.ComponentListContainer;
+import kieker.webgui.common.PluginContainer;
+import kieker.webgui.common.RepositoryContainer;
 import kieker.webgui.common.exception.NewerProjectException;
 import kieker.webgui.common.exception.ProjectLoadException;
 import kieker.webgui.common.exception.ProjectNotExistingException;
@@ -77,14 +75,13 @@ public final class CurrentCockpitEditorBean {
 	private final MIAnalysisMetaModelFactory factory = new MAnalysisMetaModelFactory();
 	@Autowired
 	private IProjectService projectService;
-	private ClassAndMethodContainer classAndMethodContainer;
 
+	private ComponentListContainer availableComponents;
 	private long currId;
 	private long timeStamp;
 	private String projectName;
 	private MIProject project;
 	private MIView activeView;
-	private ClassLoader classLoader;
 	private Dashboard dashboard;
 	private DashboardModel dashboardModel;
 	@Autowired
@@ -96,6 +93,8 @@ public final class CurrentCockpitEditorBean {
 	 * Creates a new instance of this class. <b>Do not call this constructor manually. It will only be accessed by Spring.</b>
 	 */
 	public CurrentCockpitEditorBean() {
+		this.availableComponents = new ComponentListContainer(Collections.<PluginContainer>emptyList(), Collections.<PluginContainer>emptyList(),
+				Collections.<RepositoryContainer>emptyList());
 		this.createDashboard();
 	}
 
@@ -180,9 +179,8 @@ public final class CurrentCockpitEditorBean {
 				if (this.project != null) {
 					// Remember the current time! This is important for the later comparison of the time stamps.
 					this.resetTimeStamp();
+					this.reloadComponents();
 					// Update the class loader and the specific classes used within various methods in this bean
-					this.reloadClassLoader();
-					this.reloadClassesAndMethods();
 					this.fillDashboard();
 				}
 			}
@@ -194,32 +192,10 @@ public final class CurrentCockpitEditorBean {
 	}
 
 	/**
-	 * 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.
+	 * Reloads the available components within this bean.
 	 */
-	private synchronized void reloadClassesAndMethods() throws ProjectLoadException {
-		this.classAndMethodContainer = new ClassAndMethodContainer(this.classLoader);
-	}
-
-	/**
-	 * This method reloads the class loader. In other words: The class loader will always be able to load classes from the jar-files within the lib-folder of the
-	 * project.
-	 * 
-	 * @throws ProjectLoadException
-	 *             If something went wrong.
-	 */
-	private synchronized void reloadClassLoader() throws ProjectLoadException {
-		try {
-			this.classLoader = this.projectService.getClassLoader(this.projectName, this); // NOPMD (ClassLoader)
-		} catch (final NullPointerException ex) {
-			throw new ProjectLoadException("Invalid class loader.", ex);
-		} catch (final IOException ex) {
-			throw new ProjectLoadException("Could not load classes.", ex);
-		} catch (final ProjectNotExistingException ex) {
-			throw new ProjectLoadException("Project does not exist.", ex);
-		}
+	private synchronized void reloadComponents() {
+		this.availableComponents = this.projectService.getAvailableComponents(this.projectName);
 	}
 
 	/**
@@ -251,35 +227,38 @@ public final class CurrentCockpitEditorBean {
 	}
 
 	/**
-	 * This method can be used to get the description of a {@link Display}. The description is read via the annotation using the java reflection API.
+	 * This method can be used to get the description of a {@link MIDisplay}. Currently it is a little bit expensive to search for the description.
 	 * 
 	 * @param display
 	 *            The display whose description should be extracted.
 	 * @return The description for the display or a substitute if none is available. This is in either case human readable.
 	 */
 	public synchronized String getDescription(final MIDisplay display) {
-		try {
-			final String classname = display.getParent().getClassname();
-			final String displayName = display.getName();
-			// Try to get the class
-			final Class<?> clazz = this.classLoader.loadClass(classname);
-			// Run through all methods of the class
-			for (final Method method : clazz.getMethods()) {
-				// Get the potential annotation
-				final Annotation annotationDisplay = method.getAnnotation(this.classAndMethodContainer.getDisplayAnnotationClass());
-				if (annotationDisplay != null) {
-					final String potDisplayName = (String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getDisplayNameMethod(),
-							annotationDisplay,
-							"");
-					if (potDisplayName.equals(displayName)) {
-						return (String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getDisplayDescriptionMethod(), annotationDisplay,
-								"No description available");
-					}
+		final String parentClassname = display.getParent().getClassname();
+		PluginContainer parentContainer = null;
+
+		// Find the correct parent container
+		for (final PluginContainer plugin : this.availableComponents.getFilters()) {
+			if (plugin.getPlugin().getClassname().equals(parentClassname)) {
+				parentContainer = plugin;
+				break;
+			}
+		}
+		if (parentContainer == null) {
+			for (final PluginContainer plugin : this.availableComponents.getReaders()) {
+				if (plugin.getPlugin().getClassname().equals(parentClassname)) {
+					parentContainer = plugin;
+					break;
 				}
 			}
-		} catch (final ClassNotFoundException ex) {
-			CurrentCockpitEditorBean.LOG.warn("Class not found.", ex);
 		}
+
+		// If we have now the correct parent, we can search for the correct display instance.
+		if (parentContainer != null) {
+			return parentContainer.getDisplayDescription(display.getName());
+		}
+
+		// Nothing found
 		return "No description available";
 	}
 
@@ -316,31 +295,6 @@ public final class CurrentCockpitEditorBean {
 		this.timeStamp = System.currentTimeMillis();
 	}
 
-	/**
-	 * This method delivers the available displays of the given plugin.
-	 * 
-	 * @param clazz
-	 *            The plugin whose displays should be delivered.
-	 * @return The available displays.
-	 */
-	public synchronized List<Display> getDisplays(final Class<AbstractPlugin> clazz) {
-		final List<Display> result = new ArrayList<Display>();
-
-		if (clazz != null) {
-			// Run through all available methods and find the annotated ones
-			final Method[] methods = clazz.getMethods();
-			for (final Method method : methods) {
-				final Display displayAnnot = method.getAnnotation(Display.class);
-				// Check whether the annotation is available. If yes - add it to our result list
-				if (displayAnnot != null) {
-					result.add(displayAnnot);
-				}
-			}
-		}
-
-		return result;
-	}
-
 	/**
 	 * This method adds a new view to the project.
 	 * 
@@ -487,4 +441,13 @@ public final class CurrentCockpitEditorBean {
 		this.dashboard.setModel(this.dashboardModel);
 	}
 
+	/**
+	 * Delivers the available components.
+	 * 
+	 * @return A list with the available components.
+	 */
+	public synchronized ComponentListContainer getAvailableComponents() {
+		return this.availableComponents;
+	}
+
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentUserManagementBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentUserManagementBean.java
index 1af38a827385a663b5a749cef05025dbd83f4af8..bc2be83f402a3f720ae55534c3e5c13fa90972d0 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentUserManagementBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentUserManagementBean.java
@@ -189,7 +189,7 @@ public final class CurrentUserManagementBean {
 	 * 
 	 * @return The current value of the property.
 	 */
-	public User getSelectedUser() {
+	public synchronized User getSelectedUser() {
 		return this.selectedUser;
 	}
 
@@ -198,7 +198,7 @@ public final class CurrentUserManagementBean {
 	 * 
 	 * @return The current value of the property.
 	 */
-	public User getSelectedUserCopy() {
+	public synchronized User getSelectedUserCopy() {
 		return this.selectedUserCopy;
 	}
 
@@ -208,7 +208,7 @@ public final class CurrentUserManagementBean {
 	 * @param selectedUser
 	 *            The new value of the property.
 	 */
-	public void setSelectedUser(final User selectedUser) {
+	public synchronized void setSelectedUser(final User selectedUser) {
 		// We remember the selected user, but we make also a copy. This is necessary, because otherwise we would have to do something like a rollback, if for example
 		// an edit within the DB fails.
 		this.selectedUser = selectedUser;
diff --git a/Kieker.WebGUI/src/main/webapp/pages/AnalysisEditorPage.xhtml b/Kieker.WebGUI/src/main/webapp/pages/AnalysisEditorPage.xhtml
index b7425888d8ecf41bd7a500631703bda11e00d2ef..063bbab76c3c640e9dacd484b3724130f8476364 100644
--- a/Kieker.WebGUI/src/main/webapp/pages/AnalysisEditorPage.xhtml
+++ b/Kieker.WebGUI/src/main/webapp/pages/AnalysisEditorPage.xhtml
@@ -159,97 +159,97 @@
                     <h:form id="toolpalette">
                         <p:accordionPanel multiple="true" activeIndex="0,1,2">
                             <p:tab title="#{localizedAnalysisEditorPageMessages.reader}">
-                                <ui:repeat value="#{currentAnalysisEditorBean.availableReaders}" var="reader">
-                                    <p:commandLink id="readerLink" value="#{reader.simpleName}" action="#{currentAnalysisEditorBean.addPlugin(reader)}" update=":messages" /><br/>
+                                <ui:repeat value="#{currentAnalysisEditorBean.availableComponents.readers}" var="reader">
+                                    <p:commandLink id="readerLink" value="#{reader.plugin.name}" action="#{currentAnalysisEditorBean.addPlugin(reader)}" update=":messages" disabled="#{not reader.fullyInitialized}" /><br/>
                                     <p:tooltip for="readerLink">
-                                        <b><h:outputText value="#{reader.simpleName} (#{reader.name})"/></b>
+                                        <b><h:outputText value="#{reader.plugin.name} (#{reader.plugin.classname})"/></b>
                                         <br/>
-                                        <h:outputText value="#{currentAnalysisEditorBean.getDescription(reader)}"/>
+                                        <h:outputText value="#{reader.description}"/>
                                         <br/><br/>
-                                        <ui:fragment rendered="#{not empty currentAnalysisEditorBean.getOutputPorts(reader)}">
+                                        <ui:fragment rendered="#{not empty reader.plugin.outputPorts}">
                                             <b><h:outputText value="#{localizedAnalysisEditorPageMessages.outputPorts}:"/></b>
-                                            <p:dataList value="#{currentAnalysisEditorBean.getOutputPorts(reader)}" var="port">
-                                                #{port.name()}
+                                            <p:dataList value="#{reader.plugin.outputPorts}" var="port">
+                                                #{port.name}
                                             </p:dataList>
                                         </ui:fragment>
-                                        <ui:fragment rendered="#{not empty currentAnalysisEditorBean.getRepositoryPorts(reader)}">
+                                        <ui:fragment rendered="#{not empty reader.plugin.repositories}">
                                             <b><h:outputText value="#{localizedAnalysisEditorPageMessages.repositoryPorts}:" /></b>
-                                            <p:dataList value="#{currentAnalysisEditorBean.getRepositoryPorts(reader)}" var="port">
-                                                #{port.name()}
+                                            <p:dataList value="#{reader.plugin.repositories}" var="port">
+                                                #{port.name}
                                             </p:dataList>
                                         </ui:fragment>
-                                        <ui:fragment rendered="#{not empty currentAnalysisEditorBean.getProperties(reader)}">
+                                        <ui:fragment rendered="#{not empty reader.plugin.properties}">
                                             <b><h:outputText value="#{localizedAnalysisEditorPageMessages.configuration}:"/></b>
-                                            <p:dataList value="#{currentAnalysisEditorBean.getProperties(reader)}" var="property">
-                                                #{property.name()}
+                                            <p:dataList value="#{reader.plugin.properties}" var="property">
+                                                #{property.name}
                                             </p:dataList>
                                         </ui:fragment>
-                                        <ui:fragment rendered="#{not empty currentAnalysisEditorBean.getDependencies(reader)}">
+                                        <ui:fragment rendered="#{not empty reader.dependency}">
                                             <b><h:outputText value="#{localizedAnalysisEditorPageMessages.dependencies}:"/></b>
                                             <br/>
-                                            <h:outputText value="#{currentAnalysisEditorBean.getDependencies(reader)}"/>
+                                            <h:outputText value="#{reader.dependency}"/>
                                         </ui:fragment>
                                     </p:tooltip>
                                 </ui:repeat>
                             </p:tab>
                             <p:tab title="#{localizedAnalysisEditorPageMessages.filter}">
-                                <ui:repeat value="#{currentAnalysisEditorBean.availableFilters}" var="filter">
-                                    <p:commandLink id="filterLink" value="#{filter.simpleName}" action="#{currentAnalysisEditorBean.addPlugin(filter)}" update=":messages"/><br/>
+                                <ui:repeat value="#{currentAnalysisEditorBean.availableComponents.filters}" var="filter">
+                                    <p:commandLink id="filterLink" value="#{filter.plugin.name}" action="#{currentAnalysisEditorBean.addPlugin(filter)}" update=":messages"/><br/>
                                     <p:tooltip for="filterLink">
-                                        <b><h:outputText value="#{filter.simpleName} (#{filter.name})"/></b>
+                                        <b><h:outputText value="#{filter.plugin.name} (#{filter.plugin.classname})"/></b>
                                         <br/>
-                                        <h:outputText value="#{currentAnalysisEditorBean.getDescription(filter)}"/>
+                                        <h:outputText value="#{filter.description}"/>
                                         <br/><br/>
-                                        <ui:fragment rendered="#{not empty currentAnalysisEditorBean.getInputPorts(filter)}">
+                                        <ui:fragment rendered="#{not empty filter.plugin.inputPorts}">
                                             <b><h:outputText value="#{localizedAnalysisEditorPageMessages.inputPorts}:"/></b>
-                                            <p:dataList value="#{currentAnalysisEditorBean.getInputPorts(filter)}" var="port">
-                                                #{port.name()}
+                                            <p:dataList value="#{filter.plugin.inputPorts}" var="port">
+                                                #{port.name}
                                             </p:dataList>
                                         </ui:fragment>
-                                        <ui:fragment rendered="#{not empty currentAnalysisEditorBean.getOutputPorts(filter)}">
+                                        <ui:fragment rendered="#{not empty filter.plugin.outputPorts}">
                                             <b><h:outputText value="#{localizedAnalysisEditorPageMessages.outputPorts}:"/></b>
-                                            <p:dataList value="#{currentAnalysisEditorBean.getOutputPorts(filter)}" var="port">
-                                                #{port.name()}
+                                            <p:dataList value="#{filter.plugin.outputPorts}" var="port">
+                                                #{port.name}
                                             </p:dataList>
                                         </ui:fragment>
-                                        <ui:fragment rendered="#{not empty currentAnalysisEditorBean.getRepositoryPorts(filter)}">
+                                        <ui:fragment rendered="#{not empty filter.plugin.repositories}">
                                             <b><h:outputText value="#{localizedAnalysisEditorPageMessages.repositoryPorts}:"/></b>
-                                            <p:dataList value="#{currentAnalysisEditorBean.getRepositoryPorts(filter)}" var="port">
-                                                #{port.name()}
+                                            <p:dataList value="#{filter.plugin.repositories}" var="port">
+                                                #{port.name}
                                             </p:dataList>
                                         </ui:fragment>
-                                        <ui:fragment rendered="#{not empty currentAnalysisEditorBean.getProperties(filter)}">
+                                        <ui:fragment rendered="#{not empty filter.plugin.properties}">
                                             <b><h:outputText value="#{localizedAnalysisEditorPageMessages.configuration}:"/></b>
-                                            <p:dataList value="#{currentAnalysisEditorBean.getProperties(filter)}" var="property">
-                                                #{property.name()}
+                                            <p:dataList value="#{filter.plugin.properties}" var="property">
+                                                #{property.name}
                                             </p:dataList>
                                         </ui:fragment>
-                                        <ui:fragment rendered="#{not empty currentAnalysisEditorBean.getDependencies(filter)}">
+                                        <ui:fragment rendered="#{not empty filter.dependency}">
                                             <b><h:outputText value="#{localizedAnalysisEditorPageMessages.dependencies}:"/></b>
                                             <br/>
-                                            <h:outputText value="#{currentAnalysisEditorBean.getDependencies(filter)}"/>
+                                            <h:outputText value="#{filter.dependency}"/>
                                         </ui:fragment>
                                     </p:tooltip>                                
                                 </ui:repeat>
                             </p:tab>
                             <p:tab title="#{localizedAnalysisEditorPageMessages.repositories}">
-                                <ui:repeat value="#{currentAnalysisEditorBean.availableRepositories}" var="repository">
-                                    <p:commandLink id="repositoryLink" value="#{repository.simpleName}" action="#{currentAnalysisEditorBean.addRepository(repository)}" update=":messages"/><br/>
+                                <ui:repeat value="#{currentAnalysisEditorBean.availableComponents.repositories}" var="repository">
+                                    <p:commandLink id="repositoryLink" value="#{repository.repository.name}" action="#{currentAnalysisEditorBean.addRepository(repository)}" update=":messages"/><br/>
                                     <p:tooltip for="repositoryLink">
-                                        <b><h:outputText value="#{repository.simpleName} (#{repository.name})"/></b>
+                                        <b><h:outputText value="#{repository.repository.name} (#{repository.repository.classname})"/></b>
                                         <br/>
-                                        <h:outputText value="#{currentAnalysisEditorBean.getDescription(repository)}"/>
+                                        <h:outputText value="#{repository.description}"/>
                                         <br/><br/>
-                                        <ui:fragment rendered="#{not empty currentAnalysisEditorBean.getProperties(repository)}">
+                                        <ui:fragment rendered="#{not empty repository.repository.properties}">
                                             <b><h:outputText value="#{localizedAnalysisEditorPageMessages.configuration}:"/></b>
-                                            <p:dataList value="#{currentAnalysisEditorBean.getProperties(repository)}" var="property">
-                                                #{property.name()}
+                                            <p:dataList value="#{repository.repository.properties}" var="property">
+                                                #{property.name}
                                             </p:dataList>
                                         </ui:fragment>
-                                        <ui:fragment rendered="#{not empty currentAnalysisEditorBean.getDependencies(repository)}">
+                                        <ui:fragment rendered="#{not empty repository.dependency}">
                                             <b><h:outputText value="#{localizedAnalysisEditorPageMessages.dependencies}:"/></b>
                                             <br/>
-                                            <h:outputText value="#{currentAnalysisEditorBean.getDependencies(repository)}"/>
+                                            <h:outputText value="#{repository.dependency}"/>
                                         </ui:fragment>
                                     </p:tooltip>  
                                 </ui:repeat>