Index: anches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/ApplicationDescription.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/ApplicationDescription.cs	(revision 2502)
+++ 	(revision )
@@ -1,91 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace HeuristicLab.PluginInfrastructure.Manager {
-  /// <summary>
-  /// Class that provides information about an application.
-  /// </summary>
-  [Serializable]
-  public class ApplicationDescription : IApplicationDescription {
-    private string name;
-
-    /// <summary>
-    /// Gets or sets the name of the application.
-    /// </summary>
-    public string Name {
-      get { return name; }
-      set { name = value; }
-    }
-    private Version version;
-
-    /// <summary>
-    /// Gets or sets the version of the application.
-    /// </summary>
-    public Version Version {
-      get { return version; }
-      set { version = value; }
-    }
-    private string description;
-
-    /// <summary>
-    /// Gets or sets the description of the application.
-    /// </summary>
-    public string Description {
-      get { return description; }
-      set { description = value; }
-    }
-
-    private bool autoRestart;
-    /// <summary>
-    /// Gets or sets the boolean flag if the application should be automatically restarted.
-    /// </summary>
-    public bool AutoRestart {
-      get { return autoRestart; }
-      set { autoRestart = value; }
-    }
-
-    private string declaringAssemblyName;
-    /// <summary>
-    /// Gets or sets the name of the assembly that contains the IApplication type.
-    /// </summary>
-    public string DeclaringAssemblyName {
-      get { return declaringAssemblyName; }
-      set { declaringAssemblyName = value; }
-    }
-
-    private string declaringTypeName;
-    /// <summary>
-    /// Gets or sets the name of the type that implements the interface IApplication.
-    /// </summary>
-    public string DeclaringTypeName {
-      get { return declaringTypeName; }
-      set { declaringTypeName = value; }
-    }
-
-    public override string ToString() {
-      return Name;
-    }
-  }
-}
Index: anches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/DefaultApplicationManager.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/DefaultApplicationManager.cs	(revision 2502)
+++ 	(revision )
@@ -1,219 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Security.Policy;
-using System.Reflection;
-using System.Diagnostics;
-using System.Security.Permissions;
-using System.Security;
-using System.Linq;
-using System.IO;
-
-namespace HeuristicLab.PluginInfrastructure.Manager {
-
-  public class DefaultApplicationManager : MarshalByRefObject, IApplicationManager {
-    internal event EventHandler<PluginInfrastructureEventArgs> PluginLoaded;
-    // cache for the AssemblyResolveEvent 
-    // which must be handled when assemblies are loaded dynamically after the application start
-    private Dictionary<string, Assembly> loadedAssemblies;
-
-    private List<IPluginDescription> plugins;
-    /// <summary>
-    /// Gets all plugins.
-    /// </summary>
-    public IEnumerable<IPluginDescription> Plugins {
-      get { return plugins; }
-      internal set { plugins = new List<IPluginDescription>(value); }
-    }
-
-    private List<IApplicationDescription> applications;
-    /// <summary>
-    /// Gets all installed applications.
-    /// </summary>
-    public IEnumerable<IApplicationDescription> Applications {
-      get { return applications; }
-    }
-
-    public DefaultApplicationManager()
-      : base() {
-      loadedAssemblies = new Dictionary<string, Assembly>();
-      // needed for the special case when assemblies are loaded dynamically via LoadAssemblies()
-      AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
-        if (loadedAssemblies.ContainsKey(args.Name)) {
-          return loadedAssemblies[args.Name];
-        }
-        return null;
-      };
-    }
-
-    internal void PrepareApplicationDomain(IEnumerable<IApplicationDescription> apps, IEnumerable<IPluginDescription> plugins) {
-      this.plugins = new List<IPluginDescription>(plugins);
-      this.applications = new List<IApplicationDescription>(apps);
-      PluginInfrastructure.ApplicationManager.RegisterApplicationManager(this);
-      LoadPlugins(plugins);
-    }
-
-    private void LoadPlugins(IEnumerable<IPluginDescription> plugins) {
-      // load all loadable plugins (all dependencies available) into the execution context
-      foreach (var desc in PluginDescriptionIterator.IterateInDependencyOrder(plugins.Where(x => x.PluginState != PluginState.Disabled))) {
-        foreach (string assembly in desc.Assemblies) {
-          var asm = Assembly.LoadFrom(assembly);
-
-          // instantiate and load all plugins in this assembly
-          foreach (var plugin in GetInstances<IPlugin>(asm)) {
-            plugin.OnLoad();
-          }
-        }
-        FirePluginLoaded(desc);
-        desc.Load();
-      }
-    }
-
-    internal void Run(IApplicationDescription appInfo) {
-      IApplication runnablePlugin = (IApplication)Activator.CreateInstance(appInfo.DeclaringAssemblyName, appInfo.DeclaringTypeName).Unwrap();
-      try {
-        runnablePlugin.Run();
-      }
-      catch (Exception e) {
-        throw new Exception(String.Format(
-          "Unexpected exception caught: \"{0}\"\r\n" +
-          "Type: {1}\r\n" +
-          "Plugin {2}:\r\n{3}",
-          e.Message,
-          e.GetType().FullName,
-          appInfo.Name,
-          e.ToString()));
-      }
-    }
-
-    /// <summary>
-    /// Loads assemblies dynamically from a byte array
-    /// </summary>
-    /// <param name="plugins">bytearray of all assemblies that should be loaded</param>
-    public void LoadAssemblies(IEnumerable<byte[]> assemblies) {
-      foreach (byte[] asm in assemblies) {
-        Assembly loadedAsm = Assembly.Load(asm);
-        RegisterLoadedAssembly(loadedAsm);
-      }
-    }
-
-    // register assembly in the assembly cache for the AssemblyResolveEvent
-    private void RegisterLoadedAssembly(Assembly asm) {
-      loadedAssemblies.Add(asm.FullName, asm);
-      loadedAssemblies.Add(asm.GetName().Name, asm); // add short name
-    }
-
-    /// <summary>
-    /// Creates an instance of all types that are subtypes or the same type of the specified type and declared in <paramref name="plugin"/>
-    /// </summary>
-    /// <typeparam name="T">Most general type.</typeparam>
-    /// <returns>Enumerable of the created instances.</returns>
-    public IEnumerable<T> GetInstances<T>(IPluginDescription plugin) where T : class {
-      return from t in GetTypes(typeof(T), plugin)
-             where !t.IsAbstract && !t.IsInterface && !t.HasElementType
-             select (T)Activator.CreateInstance(t);
-    }
-    /// <summary>
-    /// Creates an instance of all types declared in assembly <param name="asm"/> that are subtypes or the same type of the specified type and declared in <paramref name="plugin"/>
-    /// </summary>
-    /// <typeparam name="T">Most general type.</typeparam>
-    /// <param name="asm">Declaring assembly.</param>
-    /// <returns>Enumerable of the created instances.</returns>
-    public IEnumerable<T> GetInstances<T>(Assembly asm) where T : class {
-      return from t in GetTypes(typeof(T), asm)
-             where !t.IsAbstract && !t.IsInterface && !t.HasElementType
-             select (T)Activator.CreateInstance(t);
-    }
-    /// <summary>
-    /// Creates an instance of all types that are subtypes or the same type of the specified type
-    /// </summary>
-    /// <typeparam name="T">Most general type.</typeparam>
-    /// <returns>Enumerable of the created instances.</returns>
-    public IEnumerable<T> GetInstances<T>() where T : class {
-      return from i in GetInstances(typeof(T))
-             select (T)i;
-    }
-
-    /// <summary>
-    /// Creates an instance of all types that are subtypes or the same type of the specified type
-    /// </summary>
-    /// <typeparam name="type">Most general type.</typeparam>
-    /// <returns>Enumerable of the created instances.</returns>
-    public IEnumerable<object> GetInstances(Type type) {
-      return from t in GetTypes(type)
-             where !t.IsAbstract && !t.IsInterface && !t.HasElementType
-             select Activator.CreateInstance(t);
-    }
-
-    /// <summary>
-    /// Finds all types that are subtypes or equal to the specified type.
-    /// </summary>
-    /// <param name="type">Most general type for which to find matching types.</param>
-    /// <returns>Enumerable of the discovered types.</returns>
-    public IEnumerable<Type> GetTypes(Type type) {
-      return from asm in AppDomain.CurrentDomain.GetAssemblies()
-             from t in GetTypes(type, asm)
-             select t;
-    }
-
-    /// <summary>
-    /// Finds all types that are subtypes or equal to the specified type if they are part of the given
-    /// <paramref name="plugin"/>.
-    /// </summary>
-    /// <param name="type">Most general type for which to find matching types.</param>
-    /// <param name="plugin">The plugin the subtypes must be part of.</param>
-    /// <returns>Enumerable of the discovered types.</returns>
-    public IEnumerable<Type> GetTypes(Type type, IPluginDescription pluginDescription) {
-      return from asm in AppDomain.CurrentDomain.GetAssemblies()
-             where pluginDescription.Assemblies.Any(asmPath => Path.GetFullPath(asmPath) == Path.GetFullPath(asm.Location))
-             from t in GetTypes(type, asm)
-             select t;
-    }
-
-    /// <summary>
-    /// Gets types that are assignable (same of subtype) to the specified type only from the given assembly.
-    /// </summary>
-    /// <param name="type">Most general type we want to find.</param>
-    /// <param name="assembly">Assembly that should be searched for types.</param>
-    /// <returns>Enumerable of the discovered types.</returns>
-    private IEnumerable<Type> GetTypes(Type type, Assembly assembly) {
-      return from t in assembly.GetTypes()
-             where type.IsAssignableFrom(t)
-             select t;
-    }
-
-    private void FirePluginLoaded(IPluginDescription plugin) {
-      if (PluginLoaded != null) PluginLoaded(this, new PluginInfrastructureEventArgs("Plugin loaded", plugin));
-    }
-
-    // infinite lease time
-    /// <summary>
-    /// Initializes the life time service with infinite lease time.
-    /// </summary>
-    /// <returns><c>null</c>.</returns>
-    public override object InitializeLifetimeService() {
-      return null;
-    }
-  }
-}
-
Index: /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/HeuristicLab.PluginInfrastructure.Manager.csproj
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/HeuristicLab.PluginInfrastructure.Manager.csproj	(revision 2502)
+++ /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/HeuristicLab.PluginInfrastructure.Manager.csproj	(revision 2503)
@@ -50,8 +50,8 @@
     <Compile Include="ApplicationDescription.cs" />
     <Compile Include="DefaultApplicationManager.cs" />
-    <Compile Include="Loader.cs" />
     <Compile Include="PluginDescription.cs" />
     <Compile Include="PluginInfrastructureEventArgs.cs" />
     <Compile Include="PluginManager.cs" />
+    <Compile Include="PluginValidator.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
Index: anches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Loader.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Loader.cs	(revision 2502)
+++ 	(revision )
@@ -1,317 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Reflection;
-using System.IO;
-using System.Diagnostics;
-using System.Linq;
-
-
-namespace HeuristicLab.PluginInfrastructure.Manager {
-  internal class Loader : MarshalByRefObject {
-    internal event EventHandler<PluginInfrastructureEventArgs> PluginLoaded;
-
-    private Dictionary<PluginDescription, List<string>> pluginDependencies;
-
-    private List<ApplicationDescription> applications;
-    internal IEnumerable<ApplicationDescription> Applications {
-      get {
-        if (applications == null) DiscoverAndCheckPlugins();
-        return applications;
-      }
-    }
-
-    private IEnumerable<PluginDescription> plugins;
-    internal IEnumerable<PluginDescription> Plugins {
-      get {
-        if (plugins == null) DiscoverAndCheckPlugins();
-        return plugins;
-      }
-    }
-
-    public string PluginDir { get; set; }
-
-    public Loader() {
-      this.pluginDependencies = new Dictionary<PluginDescription, List<string>>();
-
-      // ReflectionOnlyAssemblyResolveEvent must be handled because we load assemblies from the plugin path 
-      // (which is not listed in the default assembly lookup locations)
-      AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += ReflectionOnlyAssemblyResolveEventHandler;
-    }
-
-    private Assembly ReflectionOnlyAssemblyResolveEventHandler(object sender, ResolveEventArgs args) {
-      return Assembly.ReflectionOnlyLoad(args.Name);
-    }
-
-
-    /// <summary>
-    /// Init first clears all internal datastructures (including plugin lists)
-    /// 1. All assemblies in the plugins directory are loaded into the reflection only context.
-    /// 2. The loader checks if all necessary files for each plugin are available.
-    /// 3. The loaded builds the tree of plugin descriptions (dependencies)
-    /// 4. The loader checks if all dependencies for each plugin are ok.
-    /// 5. All plugins for which there are no dependencies missing are loaded into the execution context.
-    /// 6. Each loaded plugin (all assemblies) is searched for a types that implement IPlugin
-    ///    then one instance of each IPlugin type is activated and the OnLoad hook is called.
-    /// 7. All types implementing IApplication are discovered
-    /// </summary>
-    private void DiscoverAndCheckPlugins() {
-      pluginDependencies.Clear();
-
-      IEnumerable<Assembly> reflectionOnlyAssemblies = ReflectionOnlyLoadDlls();
-      IEnumerable<PluginDescription> pluginDescriptions = GatherPluginDescriptions(reflectionOnlyAssemblies);
-      CheckPluginFiles(pluginDescriptions);
-
-      // a full list of plugin descriptions is available now we can build the dependency tree
-      BuildDependencyTree(pluginDescriptions);
-
-      // recursively check if all necessary plugins are available and not disabled
-      // disable plugins with missing or disabled dependencies
-      CheckPluginDependencies(pluginDescriptions);
-
-      // mark all plugins as enabled that were not disabled in CheckPluginFiles or CheckPluginDependencies
-      foreach (var desc in pluginDescriptions)
-        if (desc.PluginState != PluginState.Disabled)
-          desc.Enable();
-
-      // test full loading (in contrast to reflection only loading) of plugins
-      // disables plugins that are not loaded correctly
-      LoadPlugins(pluginDescriptions);
-
-      plugins = pluginDescriptions;
-      DiscoverApplications();
-    }
-
-    private void DiscoverApplications() {
-      applications = new List<ApplicationDescription>();
-
-      foreach (IApplication application in GetApplications()) {
-        ApplicationDescription info = new ApplicationDescription();
-        info.Name = application.Name;
-        info.Version = application.Version;
-        info.Description = application.Description;
-        info.AutoRestart = application.RestartOnErrors;
-        info.DeclaringAssemblyName = application.GetType().Assembly.GetName().Name;
-        info.DeclaringTypeName = application.GetType().Namespace + "." + application.GetType().Name;
-
-        applications.Add(info);
-      }
-    }
-
-    private IEnumerable<IApplication> GetApplications() {
-      return from asm in AppDomain.CurrentDomain.GetAssemblies()
-             from t in asm.GetTypes()
-             where typeof(IApplication).IsAssignableFrom(t) &&
-               !t.IsAbstract && !t.IsInterface && !t.HasElementType
-             select (IApplication)Activator.CreateInstance(t);
-    }
-
-    private IEnumerable<Assembly> ReflectionOnlyLoadDlls() {
-      List<Assembly> assemblies = new List<Assembly>();
-      // try to load each .dll file in the plugin directory into the reflection only context
-      foreach (string filename in Directory.GetFiles(PluginDir, "*.dll")) {
-        try {
-          assemblies.Add(Assembly.ReflectionOnlyLoadFrom(filename));
-        }
-        catch (BadImageFormatException) { } // just ignore the case that the .dll file is not actually a CLR dll
-      }
-      return assemblies;
-    }
-
-    // find all types implementing IPlugin in the reflectionOnlyAssemblies and create a list of plugin descriptions
-    // the dependencies in the plugin descriptions are not yet set correctly because we need to create
-    // the full list of all plugin descriptions first
-    private IEnumerable<PluginDescription> GatherPluginDescriptions(IEnumerable<Assembly> assemblies) {
-      List<PluginDescription> pluginDescriptions = new List<PluginDescription>();
-      foreach (Assembly assembly in assemblies) {
-        // GetExportedTypes throws FileNotFoundException when a referenced assembly
-        // of the current assembly is missing.
-        try {
-          foreach (Type t in assembly.GetExportedTypes()) {
-            // if there is a type that implements IPlugin
-            // use AssemblyQualifiedName to compare the types because we can't directly 
-            // compare ReflectionOnly types and Execution types
-            if (!t.IsAbstract &&
-                t.GetInterfaces().Any(x => x.AssemblyQualifiedName == typeof(IPlugin).AssemblyQualifiedName)) {
-              // fetch the attributes of the IPlugin type
-              pluginDescriptions.Add(GetPluginDescription(t));
-            }
-          }
-        }
-        // ignore exceptions. Just don't yield a plugin description when an exception is thrown
-        catch (FileNotFoundException) {
-        }
-        catch (FileLoadException) {
-        }
-        catch (InvalidPluginException) {
-        }
-      }
-      return pluginDescriptions;
-    }
-
-    /// <summary>
-    /// Extracts plugin information for this type.
-    /// Reads plugin name, list and type of files and dependencies of the plugin. This information is necessary for
-    /// plugin dependency checking before plugin activation.
-    /// </summary>
-    /// <param name="t"></param>
-    private PluginDescription GetPluginDescription(Type pluginType) {
-      // get all attributes of that type
-      IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(pluginType);
-      List<string> pluginAssemblies = new List<string>();
-      List<string> pluginDependencies = new List<string>();
-      List<string> pluginFiles = new List<string>();
-      string pluginName = null;
-      // iterate through all custom attributes and search for attributed that we are interested in 
-      foreach (CustomAttributeData attributeData in attributes) {
-        if (IsAttributeDataForType(attributeData, typeof(PluginAttribute))) {
-          pluginName = (string)attributeData.ConstructorArguments[0].Value;
-        } else if (IsAttributeDataForType(attributeData, typeof(PluginDependencyAttribute))) {
-          pluginDependencies.Add((string)attributeData.ConstructorArguments[0].Value);
-        } else if (IsAttributeDataForType(attributeData, typeof(PluginFileAttribute))) {
-          string pluginFileName = (string)attributeData.ConstructorArguments[0].Value;
-          PluginFileType fileType = (PluginFileType)attributeData.ConstructorArguments[1].Value;
-          pluginFiles.Add(Path.Combine(PluginDir, pluginFileName));
-          if (fileType == PluginFileType.Assembly) {
-            pluginAssemblies.Add(Path.Combine(PluginDir, pluginFileName));
-          }
-        }
-      }
-
-      // minimal sanity check of the attribute values
-      if (!string.IsNullOrEmpty(pluginName) &&
-          pluginFiles.Count > 0 &&
-          pluginAssemblies.Count > 0) {
-        // create a temporary PluginDescription that contains the attribute values
-        PluginDescription info = new PluginDescription();
-        info.Name = pluginName;
-        info.Version = pluginType.Assembly.GetName().Version;
-        info.AddAssemblies(pluginAssemblies);
-        info.AddFiles(pluginFiles);
-
-        this.pluginDependencies[info] = pluginDependencies;
-        return info;
-      } else {
-        throw new InvalidPluginException("Invalid metadata in plugin " + pluginType.ToString());
-      }
-    }
-
-    private bool IsAttributeDataForType(CustomAttributeData attributeData, Type attributeType) {
-      return attributeData.Constructor.DeclaringType.AssemblyQualifiedName == attributeType.AssemblyQualifiedName;
-    }
-
-    // builds a dependency tree of all plugin descriptions
-    // searches matching plugin descriptions based on the list of dependency names for each plugin
-    // and sets the dependencies in the plugin descriptions
-    private void BuildDependencyTree(IEnumerable<PluginDescription> pluginDescriptions) {
-      foreach (var desc in pluginDescriptions) {
-        foreach (string pluginName in pluginDependencies[desc]) {
-          var matchingDescriptions = pluginDescriptions.Where(x => x.Name == pluginName);
-          if (matchingDescriptions.Count() > 0) {
-            desc.AddDependency(matchingDescriptions.First());
-          } else {
-            // no plugin description that matches the dependency name is available => plugin is disabled
-            desc.Disable();
-            break; // stop processing more dependencies
-          }
-        }
-      }
-    }
-
-    private void CheckPluginDependencies(IEnumerable<PluginDescription> pluginDescriptions) {
-      foreach (PluginDescription pluginDescription in pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled)) {
-        if (IsAnyDependencyDisabled(pluginDescription)) {
-          // PluginDescription.Message = "Disabled: missing plugin dependency.";
-          pluginDescription.Disable();
-        }
-      }
-    }
-
-
-    private bool IsAnyDependencyDisabled(PluginDescription descr) {
-      if (descr.PluginState == PluginState.Disabled) return true;
-      foreach (PluginDescription dependency in descr.Dependencies) {
-        if (IsAnyDependencyDisabled(dependency)) return true;
-      }
-      return false;
-    }
-
-    private void LoadPlugins(IEnumerable<PluginDescription> pluginDescriptions) {
-      // load all loadable plugins (all dependencies available) into the execution context
-      foreach (var desc in PluginDescriptionIterator.IterateInDependencyOrder(pluginDescriptions
-                                                                                .Cast<IPluginDescription>()
-                                                                                .Where(x => x.PluginState != PluginState.Disabled))) {
-        List<Type> types = new List<Type>();
-        foreach (string assembly in desc.Assemblies) {
-          var asm = Assembly.LoadFrom(assembly);
-          foreach (Type t in asm.GetTypes()) {
-            if (typeof(IPlugin).IsAssignableFrom(t)) {
-              types.Add(t);
-            }
-          }
-        }
-
-        foreach (Type pluginType in types) {
-          if (!pluginType.IsAbstract && !pluginType.IsInterface && !pluginType.HasElementType) {
-            IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType);
-            plugin.OnLoad();
-            FirePluginLoaded(plugin.Name);
-          }
-        }
-        desc.Load();
-      }
-    }
-
-    // checks if all declared plugin files are actually available and disables plugins with missing files
-    private void CheckPluginFiles(IEnumerable<PluginDescription> pluginDescriptions) {
-      foreach (PluginDescription desc in pluginDescriptions) {
-        if (!CheckPluginFiles(desc)) {
-          desc.Disable();
-        }
-      }
-    }
-
-    private bool CheckPluginFiles(PluginDescription PluginDescription) {
-      foreach (string filename in PluginDescription.Files) {
-        if (!File.Exists(filename)) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    private void FirePluginLoaded(string pluginName) {
-      if (PluginLoaded != null)
-        PluginLoaded(this, new PluginInfrastructureEventArgs("Plugin loaded", pluginName));
-    }
-
-    /// <summary>
-    /// Initializes the life time service with an infinite lease time.
-    /// </summary>
-    /// <returns><c>null</c>.</returns>
-    public override object InitializeLifetimeService() {
-      return null;
-    }
-  }
-}
Index: anches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginDescription.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginDescription.cs	(revision 2502)
+++ 	(revision )
@@ -1,169 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace HeuristicLab.PluginInfrastructure.Manager {
-  /// <summary>
-  /// Holds information of loaded plugins that is needed for plugin management.
-  /// Used to represent plugins in AppDomains without loading the plugin assemblies.
-  /// </summary>
-  [Serializable]
-  public class PluginDescription : IPluginDescription {
-    private string name;
-    /// <summary>
-    /// Gets or sets the name of the plugin.
-    /// </summary>
-    public string Name {
-      get { return name; }
-      set { name = value; }
-    }
-    private Version version;
-    /// <summary>
-    /// Gets or sets the version of the plugin.
-    /// </summary>
-    public Version Version {
-      get { return version; }
-      set { version = value; }
-    }
-    private DateTime buildDate;
-    /// <summary>
-    /// Gets or sets the build date of the plugin.
-    /// </summary>
-    public DateTime BuildDate {
-      get { return buildDate; }
-      set { buildDate = value; }
-    }
-
-    private PluginState pluginState;
-    /// <summary>
-    /// Gets or sets the plugin state.
-    /// </summary>
-    public PluginState PluginState {
-      get { return pluginState; }
-    }
-
-    private int nTimesLoaded;
-    public void Disable() {
-      if (pluginState != PluginState.Undefined)
-        throw new InvalidOperationException("Can't disabled a plugin in state " + pluginState);
-      pluginState = PluginState.Disabled;
-    }
-
-    public void Enable() {
-      if (pluginState != PluginState.Undefined)
-        throw new InvalidOperationException("Can't enabled a plugin in state " + pluginState);
-      pluginState = PluginState.Enabled;
-    }
-
-    public void Load() {
-      if (!(pluginState == PluginState.Enabled || pluginState == PluginState.Loaded))
-        throw new InvalidOperationException("Can't loaded a plugin in state " + pluginState);
-      pluginState = PluginState.Loaded;
-      nTimesLoaded++;
-    }
-
-    public void Unload() {
-      if (pluginState != PluginState.Loaded)
-        throw new InvalidOperationException("Can't unload a plugin in state " + pluginState);
-      nTimesLoaded--;
-      if (nTimesLoaded == 0) pluginState = PluginState.Enabled;
-    }
-
-    private List<string> files = new List<string>();
-    /// <summary>
-    /// Gets the names of all files that belong to this plugin.
-    /// These files are deleted when the plugin is removed or updated.
-    /// </summary>
-    public IEnumerable<string> Files {
-      get { return files; }
-    }
-
-    internal void AddFiles(IEnumerable<string> fileNames) {
-      files.AddRange(fileNames);
-    }
-
-    private List<IPluginDescription> dependencies = new List<IPluginDescription>();
-    /// <summary>
-    /// Gets all dependencies of the plugin.
-    /// </summary>
-    public IEnumerable<IPluginDescription> Dependencies {
-      get { return dependencies; }
-    }
-
-    public void AddDependency(PluginDescription dependency) {
-      dependencies.Add(dependency);
-    }
-
-
-    private List<string> assemblies = new List<string>();
-    /// <summary>
-    /// Gets the names of the assemblies that belong to this plugin.
-    /// </summary>
-    public IEnumerable<string> Assemblies {
-      get { return assemblies; }
-      // set { assemblies = value; }
-    }
-
-    internal void AddAssemblies(IEnumerable<string> assemblyNames) {
-      assemblies.AddRange(assemblyNames);
-    }
-
-    public PluginDescription() {
-      nTimesLoaded = 0;
-      pluginState = PluginState.Undefined;
-    }
-
-    /// <summary>
-    /// Gets the string representation of the plugin.
-    /// </summary>
-    /// <returns>The name of the plugin.</returns>
-    public override string ToString() {
-      return Name;
-    }
-
-    // equals and hashcode have to be implemented because we want to compare PluginDescriptions from 
-    // different AppDomains and serialization destroys reference equality
-    /// <summary>
-    /// Checks whether the given object is equal to the current plugin.
-    /// </summary>
-    /// <param name="obj">The object to compare.</param>
-    /// <returns><c>true</c> if it is equal, <c>false</c> otherwise.</returns>
-    public override bool Equals(object obj) {
-      if (!(obj is PluginDescription))
-        return false;
-      PluginDescription other = (PluginDescription)obj;
-
-      return other.Name == this.Name && other.Version == this.Version;
-    }
-    /// <summary>
-    /// Gets the hash code of the current plugin.
-    /// </summary>
-    /// <returns>The hash code of the plugin.</returns>
-    public override int GetHashCode() {
-      if (version != null) {
-        return name.GetHashCode() + version.GetHashCode();
-      } else return name.GetHashCode();
-    }
-  }
-}
Index: anches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginInfrastructureEventArgs.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginInfrastructureEventArgs.cs	(revision 2502)
+++ 	(revision )
@@ -1,37 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace HeuristicLab.PluginInfrastructure {
-  // to be replaced by GenericEventArgs
-  [Serializable]
-  public class PluginInfrastructureEventArgs : EventArgs {
-    public string Action { get; private set; }
-    public object Entity { get; private set; }
-    public PluginInfrastructureEventArgs(string action, object entity) {
-      this.Action = action;
-      this.Entity = entity;
-    }
-  }
-}
Index: anches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginManager.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginManager.cs	(revision 2502)
+++ 	(revision )
@@ -1,140 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Security.Policy;
-using System.Reflection;
-using System.Diagnostics;
-using System.Security.Permissions;
-using System.Security;
-using System.Linq;
-
-namespace HeuristicLab.PluginInfrastructure.Manager {
-
-  // must extend MarshalByRefObject because of event passing between Loader and PluginManager (each in it's own AppDomain)
-  /// <summary>
-  /// Class to manage different plugins.
-  /// </summary>
-  public class PluginManager : MarshalByRefObject {
-    /// <summary>
-    /// Event handler for actions in the plugin manager.
-    /// </summary>
-    public event EventHandler<PluginInfrastructureEventArgs> Action;
-
-    private string pluginDir;
-
-    public PluginManager(string pluginDir) {
-      this.pluginDir = pluginDir;
-    }
-
-    private List<PluginDescription> plugins;
-
-    private List<ApplicationDescription> applications;
-    /// <summary>
-    /// Gets all installed applications.
-    /// </summary>
-    public IEnumerable<ApplicationDescription> Applications {
-      get { return applications; }
-    }
-
-    /// <summary>
-    /// Determines installed plugins and checks if all plugins are loadable.
-    /// </summary>
-    public void DiscoverAndCheckPlugins() {
-      FireAction("Initializing", "PluginInfrastructure");
-      AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
-      setup.PrivateBinPath = pluginDir;
-      AppDomain pluginDomain = null;
-      try {
-        pluginDomain = AppDomain.CreateDomain("plugin domain", null, setup);
-        Loader remoteLoader = (Loader)pluginDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.Loader");
-        remoteLoader.PluginDir = pluginDir;
-        // forward all events from the remoteLoader to listeners
-        remoteLoader.PluginLoaded += delegate(object sender, PluginInfrastructureEventArgs args) { FireAction(args.Action, args.Entity); };
-        this.plugins = new List<PluginDescription>(remoteLoader.Plugins);
-        this.applications = new List<ApplicationDescription>(remoteLoader.Applications);
-        FireAction("Initialized", "PluginInfrastructure");
-      }
-      finally {
-        // discard the AppDomain that was used for plugin discovery
-        UnloadAppDomain(pluginDomain);
-      }
-    }
-
-
-    /// <summary>
-    /// Creates a separate AppDomain.
-    /// Loads all active plugin assemblies and starts the application in the new AppDomain via a PluginRunner instance activated in the new AppDomain
-    /// </summary>
-    /// <param name="appInfo">application to run</param>
-    public void Run(ApplicationDescription appInfo) {
-      // create a separate AppDomain for the application
-      // initialize the static ApplicationManager in the AppDomain
-      // and remotely tell it to start the application
-
-      FireAction("Starting application", appInfo.Name);
-      AppDomain applicationDomain = null;
-      try {
-        AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
-        setup.PrivateBinPath = pluginDir;
-        applicationDomain = AppDomain.CreateDomain(appInfo.Name, null, setup);
-        DefaultApplicationManager applicationManager =
-          (DefaultApplicationManager)applicationDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.DefaultApplicationManager");
-        applicationManager.PluginLoaded += applicationManager_PluginLoaded;
-        applicationManager.PrepareApplicationDomain(
-          new List<IApplicationDescription>(applications.Cast<IApplicationDescription>()),
-          new List<IPluginDescription>(plugins.Cast<IPluginDescription>()));
-        FireAction("Started application", appInfo.Name);
-        applicationManager.Run(appInfo);
-      }
-      finally {
-        // make sure domain is unloaded in all cases
-        UnloadAppDomain(applicationDomain);
-      }
-    }
-
-    void applicationManager_PluginLoaded(object sender, PluginInfrastructureEventArgs e) {
-      // load the matching plugin description (
-      PluginDescription desc = (PluginDescription)e.Entity;
-      foreach (var myDesc in plugins) {
-        if (myDesc.Equals(desc)) myDesc.Load();
-      }
-      FireAction(e.Action, e.Entity);
-    }
-
-    private void UnloadAppDomain(AppDomain appDomain) {
-      AppDomain.Unload(appDomain);
-
-      // TODO: Update plugin descriptions in all active AppDomains
-
-      // unload all plugins
-      foreach (var pluginDescription in plugins)
-        pluginDescription.Unload();
-    }
-
-    private void FireAction(string action, object entity) {
-      if (Action != null) {
-        Action(this, new PluginInfrastructureEventArgs(action, entity));
-      }
-    }
-  }
-}
Index: anches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Runner.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Runner.cs	(revision 2502)
+++ 	(revision )
@@ -1,116 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Reflection;
-using System.Security.Permissions;
-using System.Security;
-using System.Linq;
-
-namespace HeuristicLab.PluginInfrastructure.Manager {
-  public class Runner : MarshalByRefObject {
-    internal event PluginManagerActionEventHandler PluginAction;
-
-    private Dictionary<string, Assembly> loadedAssemblies;
-
-    public Runner() {
-      loadedAssemblies = new Dictionary<string, Assembly>();
-      AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
-        if (loadedAssemblies.ContainsKey(args.Name)) {
-          return loadedAssemblies[args.Name];
-        }
-        return null;
-      };
-    }
-
-    public void LoadPlugins(IEnumerable<IPluginDescription> pluginDescriptions) {
-      //FileIOPermission fileperm = new FileIOPermission(FileIOPermissionAccess.AllAccess, @"C:\Program Files\HeuristicLab 3.0\plugins\");
-      //fileperm.Assert();
-
-      // load all loadable plugins (all dependencies available) into the execution context
-      foreach (var desc in PluginDescriptionIterator.IterateInDependencyOrder(pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled))) {
-        List<Type> types = new List<Type>();
-        foreach (string assembly in desc.Assemblies) {
-          var asm = Assembly.LoadFrom(assembly);
-          foreach (Type t in asm.GetTypes()) {
-            if (typeof(IPlugin).IsAssignableFrom(t)) {
-              types.Add(t);
-            }
-          }
-        }
-
-        foreach (Type pluginType in types) {
-          if (!pluginType.IsAbstract && !pluginType.IsInterface && !pluginType.HasElementType) {
-            IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType);
-            plugin.OnLoad();
-            desc.Load();
-            PluginAction(this, new PluginManagerActionEventArgs(plugin.Name, PluginManagerAction.PluginLoaded));
-          }
-        }
-      }
-      //CodeAccessPermission.RevertAssert();
-    }
-
-    /// <summary>
-    /// Loads assemblies from a byte array
-    /// </summary>
-    /// <param name="plugins">bytearray of all assemblies that should be loaded</param>
-    public void LoadAssemblies(IEnumerable<byte[]> assemblies) {
-      foreach (byte[] asm in assemblies) {
-        Assembly loadedAsm = Assembly.Load(asm);
-        RegisterLoadedAssembly(loadedAsm);
-      }
-    }
-
-    private void RegisterLoadedAssembly(Assembly asm) {
-      loadedAssemblies.Add(asm.FullName, asm);
-      loadedAssemblies.Add(asm.GetName().Name, asm); // add short name
-    }
-
-    public void Run(ApplicationDescription appInfo) {
-      IApplication runnablePlugin = (IApplication)Activator.CreateInstance(appInfo.DeclaringAssemblyName, appInfo.DeclaringTypeName).Unwrap();
-      try {
-        runnablePlugin.Run();
-      }
-      catch (Exception e) {
-        throw new Exception(String.Format(
-          "Unexpected exception caught: \"{0}\"\r\n" +
-          "Type: {1}\r\n" +
-          "Plugin {2}:\r\n{3}",
-          e.Message,
-          e.GetType().FullName,
-          appInfo.Name,
-          e.ToString()));
-      }
-    }
-
-    // infinite lease time
-    /// <summary>
-    /// Initializes the life time service with infinite lease time.
-    /// </summary>
-    /// <returns><c>null</c>.</returns>
-    public override object InitializeLifetimeService() {
-      return null;
-    }
-  }
-}
Index: /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/ApplicationDescription.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/ApplicationDescription.cs	(revision 2503)
+++ /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/ApplicationDescription.cs	(revision 2503)
@@ -0,0 +1,91 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace HeuristicLab.PluginInfrastructure.Manager {
+  /// <summary>
+  /// Class that provides information about an application.
+  /// </summary>
+  [Serializable]
+  public class ApplicationDescription : IApplicationDescription {
+    private string name;
+
+    /// <summary>
+    /// Gets or sets the name of the application.
+    /// </summary>
+    public string Name {
+      get { return name; }
+      set { name = value; }
+    }
+    private Version version;
+
+    /// <summary>
+    /// Gets or sets the version of the application.
+    /// </summary>
+    public Version Version {
+      get { return version; }
+      set { version = value; }
+    }
+    private string description;
+
+    /// <summary>
+    /// Gets or sets the description of the application.
+    /// </summary>
+    public string Description {
+      get { return description; }
+      set { description = value; }
+    }
+
+    private bool autoRestart;
+    /// <summary>
+    /// Gets or sets the boolean flag if the application should be automatically restarted.
+    /// </summary>
+    public bool AutoRestart {
+      get { return autoRestart; }
+      set { autoRestart = value; }
+    }
+
+    private string declaringAssemblyName;
+    /// <summary>
+    /// Gets or sets the name of the assembly that contains the IApplication type.
+    /// </summary>
+    public string DeclaringAssemblyName {
+      get { return declaringAssemblyName; }
+      set { declaringAssemblyName = value; }
+    }
+
+    private string declaringTypeName;
+    /// <summary>
+    /// Gets or sets the name of the type that implements the interface IApplication.
+    /// </summary>
+    public string DeclaringTypeName {
+      get { return declaringTypeName; }
+      set { declaringTypeName = value; }
+    }
+
+    public override string ToString() {
+      return Name;
+    }
+  }
+}
Index: /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/ApplicationManager.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/ApplicationManager.cs	(revision 2502)
+++ /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/ApplicationManager.cs	(revision 2503)
@@ -31,11 +31,22 @@
 namespace HeuristicLab.PluginInfrastructure {
 
+  /// <summary>
+  /// The ApplicationManager has a reference to the application manager singleton.
+  /// The application manager provides
+  /// </summary>
   public static class ApplicationManager {
     private static IApplicationManager appManager;
+    /// <summary>
+    /// Gets the application manager singleton.
+    /// </summary>
     public static IApplicationManager Manager {
       get { return appManager; }
     }
 
-    public static void RegisterApplicationManager(IApplicationManager manager) {
+    /// <summary>
+    /// Registers a new application manager.
+    /// </summary>
+    /// <param name="manager"></param>
+    internal static void RegisterApplicationManager(IApplicationManager manager) {
       if (appManager != null) throw new InvalidOperationException("The application manager has already been set.");
       appManager = manager;
Index: /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/BaseClasses/PluginBase.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/BaseClasses/PluginBase.cs	(revision 2502)
+++ /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/BaseClasses/PluginBase.cs	(revision 2503)
@@ -56,29 +56,4 @@
     }
 
-    ///// <inheritdoc />
-    //public Version Version {
-    //  get {
-    //    var pluginAttribute = PluginDescriptionAttribute;
-    //    // if the version is not set in the attribute then the version of the assembly is used as default
-    //    if (string.IsNullOrEmpty(pluginAttribute.Version)) {
-    //      return this.GetType().Assembly.GetName().Version;
-    //    } else {
-    //      return new Version(pluginAttribute.Version);
-    //    }
-    //  }
-    //}
-
-    ///// <inheritdoc />
-    //public string Description {
-    //  get {
-    //    var pluginAttribute = PluginDescriptionAttribute;
-    //    // if the description is not explicitly set in the attribute then the name of the plugin is used as default
-    //    if (string.IsNullOrEmpty(pluginAttribute.Description)) {
-    //      return pluginAttribute.Name;
-    //    } else {
-    //      return pluginAttribute.Description;
-    //    }
-    //  }
-    //}
 
     /// <inheritdoc/>
@@ -94,4 +69,6 @@
     /// <inhertitdoc>
     public virtual void OnLoad() { }
+    /// <inhertitdoc>
+    public virtual void OnUnload() { }
     #endregion
 
Index: /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/DefaultApplicationManager.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/DefaultApplicationManager.cs	(revision 2503)
+++ /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/DefaultApplicationManager.cs	(revision 2503)
@@ -0,0 +1,239 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Security.Policy;
+using System.Reflection;
+using System.Diagnostics;
+using System.Security.Permissions;
+using System.Security;
+using System.Linq;
+using System.IO;
+
+namespace HeuristicLab.PluginInfrastructure.Manager {
+
+  public sealed class DefaultApplicationManager : MarshalByRefObject, IApplicationManager {
+    internal event EventHandler<PluginInfrastructureEventArgs> PluginLoaded;
+    internal event EventHandler<PluginInfrastructureEventArgs> PluginUnloaded;
+
+    // cache for the AssemblyResolveEvent 
+    // which must be handled when assemblies are loaded dynamically after the application start
+    private Dictionary<string, Assembly> loadedAssemblies;
+
+    private List<IPlugin> loadedPlugins;
+
+    private List<IPluginDescription> plugins;
+    /// <summary>
+    /// Gets all plugins.
+    /// </summary>
+    public IEnumerable<IPluginDescription> Plugins {
+      get { return plugins; }
+      internal set { plugins = new List<IPluginDescription>(value); }
+    }
+
+    private List<IApplicationDescription> applications;
+    /// <summary>
+    /// Gets all installed applications.
+    /// </summary>
+    public IEnumerable<IApplicationDescription> Applications {
+      get { return applications; }
+    }
+
+    internal DefaultApplicationManager()
+      : base() {
+      loadedAssemblies = new Dictionary<string, Assembly>();
+      loadedPlugins = new List<IPlugin>();
+      // needed for the special case when assemblies are loaded dynamically via LoadAssemblies()
+      AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
+        if (loadedAssemblies.ContainsKey(args.Name)) {
+          return loadedAssemblies[args.Name];
+        }
+        return null;
+      };
+    }
+
+    internal void PrepareApplicationDomain(IEnumerable<IApplicationDescription> apps, IEnumerable<IPluginDescription> plugins) {
+      this.plugins = new List<IPluginDescription>(plugins);
+      this.applications = new List<IApplicationDescription>(apps);
+      PluginInfrastructure.ApplicationManager.RegisterApplicationManager(this);
+      LoadPlugins(plugins);
+    }
+
+    private void LoadPlugins(IEnumerable<IPluginDescription> plugins) {
+      // load all loadable plugins (all dependencies available) into the execution context
+      foreach (var desc in PluginDescriptionIterator.IterateInDependencyOrder(plugins.Where(x => x.PluginState != PluginState.Disabled))) {
+        foreach (string assembly in desc.Assemblies) {
+          var asm = Assembly.LoadFrom(assembly);
+
+          // instantiate and load all plugins in this assembly
+          foreach (var plugin in GetInstances<IPlugin>(asm)) {
+            plugin.OnLoad();
+            loadedPlugins.Add(plugin);
+          }
+        }
+        OnPluginLoaded(new PluginInfrastructureEventArgs("Plugin loaded", desc));
+        desc.Load();
+      }
+    }
+
+    internal void Run(IApplicationDescription appInfo) {
+      IApplication runnablePlugin = (IApplication)Activator.CreateInstance(appInfo.DeclaringAssemblyName, appInfo.DeclaringTypeName).Unwrap();
+      try {
+        runnablePlugin.Run();
+      }
+      catch (Exception e) {
+        throw new Exception(String.Format(
+          "Unexpected exception caught: \"{0}\"\r\n" +
+          "Type: {1}\r\n" +
+          "Plugin {2}:\r\n{3}",
+          e.Message,
+          e.GetType().FullName,
+          appInfo.Name,
+          e.ToString()));
+      }
+      finally {
+        // unload plugins in reverse order
+        foreach (var plugin in loadedPlugins.Reverse<IPlugin>()) {
+          plugin.OnUnload();
+        }
+        foreach (var desc in PluginDescriptionIterator.IterateInDependencyOrder(plugins.Where(x => x.PluginState != PluginState.Disabled))) {
+          desc.Unload();
+          OnPluginUnloaded(new PluginInfrastructureEventArgs("Plugin unloaded", desc));
+        }
+      }
+    }
+
+    /// <summary>
+    /// Loads assemblies dynamically from a byte array
+    /// </summary>
+    /// <param name="plugins">bytearray of all assemblies that should be loaded</param>
+    public void LoadAssemblies(IEnumerable<byte[]> assemblies) {
+      foreach (byte[] asm in assemblies) {
+        Assembly loadedAsm = Assembly.Load(asm);
+        RegisterLoadedAssembly(loadedAsm);
+      }
+    }
+
+    // register assembly in the assembly cache for the AssemblyResolveEvent
+    private void RegisterLoadedAssembly(Assembly asm) {
+      loadedAssemblies.Add(asm.FullName, asm);
+      loadedAssemblies.Add(asm.GetName().Name, asm); // add short name
+    }
+
+    /// <summary>
+    /// Creates an instance of all types that are subtypes or the same type of the specified type and declared in <paramref name="plugin"/>
+    /// </summary>
+    /// <typeparam name="T">Most general type.</typeparam>
+    /// <returns>Enumerable of the created instances.</returns>
+    public IEnumerable<T> GetInstances<T>(IPluginDescription plugin) where T : class {
+      return from t in GetTypes(typeof(T), plugin)
+             where !t.IsAbstract && !t.IsInterface && !t.HasElementType
+             select (T)Activator.CreateInstance(t);
+    }
+    /// <summary>
+    /// Creates an instance of all types declared in assembly <param name="asm"/> that are subtypes or the same type of the specified type and declared in <paramref name="plugin"/>
+    /// </summary>
+    /// <typeparam name="T">Most general type.</typeparam>
+    /// <param name="asm">Declaring assembly.</param>
+    /// <returns>Enumerable of the created instances.</returns>
+    public IEnumerable<T> GetInstances<T>(Assembly asm) where T : class {
+      return from t in GetTypes(typeof(T), asm)
+             where !t.IsAbstract && !t.IsInterface && !t.HasElementType
+             select (T)Activator.CreateInstance(t);
+    }
+    /// <summary>
+    /// Creates an instance of all types that are subtypes or the same type of the specified type
+    /// </summary>
+    /// <typeparam name="T">Most general type.</typeparam>
+    /// <returns>Enumerable of the created instances.</returns>
+    public IEnumerable<T> GetInstances<T>() where T : class {
+      return from i in GetInstances(typeof(T))
+             select (T)i;
+    }
+
+    /// <summary>
+    /// Creates an instance of all types that are subtypes or the same type of the specified type
+    /// </summary>
+    /// <typeparam name="type">Most general type.</typeparam>
+    /// <returns>Enumerable of the created instances.</returns>
+    public IEnumerable<object> GetInstances(Type type) {
+      return from t in GetTypes(type)
+             where !t.IsAbstract && !t.IsInterface && !t.HasElementType
+             select Activator.CreateInstance(t);
+    }
+
+    /// <summary>
+    /// Finds all types that are subtypes or equal to the specified type.
+    /// </summary>
+    /// <param name="type">Most general type for which to find matching types.</param>
+    /// <returns>Enumerable of the discovered types.</returns>
+    public IEnumerable<Type> GetTypes(Type type) {
+      return from asm in AppDomain.CurrentDomain.GetAssemblies()
+             from t in GetTypes(type, asm)
+             select t;
+    }
+
+    /// <summary>
+    /// Finds all types that are subtypes or equal to the specified type if they are part of the given
+    /// <paramref name="plugin"/>.
+    /// </summary>
+    /// <param name="type">Most general type for which to find matching types.</param>
+    /// <param name="plugin">The plugin the subtypes must be part of.</param>
+    /// <returns>Enumerable of the discovered types.</returns>
+    public IEnumerable<Type> GetTypes(Type type, IPluginDescription pluginDescription) {
+      return from asm in AppDomain.CurrentDomain.GetAssemblies()
+             where pluginDescription.Assemblies.Any(asmPath => Path.GetFullPath(asmPath) == Path.GetFullPath(asm.Location))
+             from t in GetTypes(type, asm)
+             select t;
+    }
+
+    /// <summary>
+    /// Gets types that are assignable (same of subtype) to the specified type only from the given assembly.
+    /// </summary>
+    /// <param name="type">Most general type we want to find.</param>
+    /// <param name="assembly">Assembly that should be searched for types.</param>
+    /// <returns>Enumerable of the discovered types.</returns>
+    private IEnumerable<Type> GetTypes(Type type, Assembly assembly) {
+      return from t in assembly.GetTypes()
+             where type.IsAssignableFrom(t)
+             select t;
+    }
+
+    private void OnPluginLoaded(PluginInfrastructureEventArgs e) {
+      if (PluginLoaded != null) PluginLoaded(this, e);
+    }
+
+    private void OnPluginUnloaded(PluginInfrastructureEventArgs e) {
+      if (PluginUnloaded != null) PluginUnloaded(this, e);
+    }
+
+    // infinite lease time
+    /// <summary>
+    /// Initializes the life time service with infinite lease time.
+    /// </summary>
+    /// <returns><c>null</c>.</returns>
+    public override object InitializeLifetimeService() {
+      return null;
+    }
+  }
+}
+
Index: /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/HeuristicLab.PluginInfrastructure.csproj
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/HeuristicLab.PluginInfrastructure.csproj	(revision 2502)
+++ /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/HeuristicLab.PluginInfrastructure.csproj	(revision 2503)
@@ -86,4 +86,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="ApplicationDescription.cs" />
     <Compile Include="Attributes\ApplicationAttribute.cs" />
     <Compile Include="Attributes\AssemblyBuildDateAttribute.cs" />
@@ -93,4 +94,5 @@
     <Compile Include="BaseClasses\ApplicationBase.cs" />
     <Compile Include="BaseClasses\PluginBase.cs" />
+    <Compile Include="DefaultApplicationManager.cs" />
     <Compile Include="Interfaces\IApplicationManager.cs" />
     <Compile Include="Interfaces\IApplicationDescription.cs" />
@@ -102,7 +104,11 @@
     <Compile Include="Interfaces\IPluginDescription.cs" />
     <Compile Include="InvalidPluginException.cs" />
+    <Compile Include="PluginDescription.cs" />
     <Compile Include="PluginDescriptionIterator.cs" />
     <Compile Include="ApplicationManager.cs" />
+    <Compile Include="PluginInfrastructureEventArgs.cs" />
+    <Compile Include="PluginManager.cs" />
     <Compile Include="PluginState.cs" />
+    <Compile Include="PluginValidator.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <EmbeddedResource Include="Properties\Resources.resx">
@@ -129,4 +135,7 @@
     </Compile>
   </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Manager\" />
+  </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Interfaces/IPlugin.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Interfaces/IPlugin.cs	(revision 2502)
+++ /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Interfaces/IPlugin.cs	(revision 2503)
@@ -51,4 +51,10 @@
     /// </summary>
     void OnLoad();
+
+    /// <summary>
+    /// Called by the framework whenever the plugin is unloaded.
+    /// Plugins are unloaded when an application exits.
+    /// </summary>
+    void OnUnload();
   }
 }
Index: /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginDescription.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginDescription.cs	(revision 2503)
+++ /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginDescription.cs	(revision 2503)
@@ -0,0 +1,169 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace HeuristicLab.PluginInfrastructure.Manager {
+  /// <summary>
+  /// Holds information of loaded plugins that is needed for plugin management.
+  /// Used to represent plugins in AppDomains without loading the plugin assemblies.
+  /// </summary>
+  [Serializable]
+  public class PluginDescription : IPluginDescription {
+    private string name;
+    /// <summary>
+    /// Gets or sets the name of the plugin.
+    /// </summary>
+    public string Name {
+      get { return name; }
+      set { name = value; }
+    }
+    private Version version;
+    /// <summary>
+    /// Gets or sets the version of the plugin.
+    /// </summary>
+    public Version Version {
+      get { return version; }
+      set { version = value; }
+    }
+    private DateTime buildDate;
+    /// <summary>
+    /// Gets or sets the build date of the plugin.
+    /// </summary>
+    public DateTime BuildDate {
+      get { return buildDate; }
+      set { buildDate = value; }
+    }
+
+    private PluginState pluginState;
+    /// <summary>
+    /// Gets or sets the plugin state.
+    /// </summary>
+    public PluginState PluginState {
+      get { return pluginState; }
+    }
+
+    private int nTimesLoaded;
+    public void Disable() {
+      if (pluginState != PluginState.Undefined)
+        throw new InvalidOperationException("Can't disabled a plugin in state " + pluginState);
+      pluginState = PluginState.Disabled;
+    }
+
+    public void Enable() {
+      if (pluginState != PluginState.Undefined)
+        throw new InvalidOperationException("Can't enabled a plugin in state " + pluginState);
+      pluginState = PluginState.Enabled;
+    }
+
+    public void Load() {
+      if (!(pluginState == PluginState.Enabled || pluginState == PluginState.Loaded))
+        throw new InvalidOperationException("Can't loaded a plugin in state " + pluginState);
+      pluginState = PluginState.Loaded;
+      nTimesLoaded++;
+    }
+
+    public void Unload() {
+      if (pluginState != PluginState.Loaded)
+        throw new InvalidOperationException("Can't unload a plugin in state " + pluginState);
+      nTimesLoaded--;
+      if (nTimesLoaded == 0) pluginState = PluginState.Enabled;
+    }
+
+    private List<string> files = new List<string>();
+    /// <summary>
+    /// Gets the names of all files that belong to this plugin.
+    /// These files are deleted when the plugin is removed or updated.
+    /// </summary>
+    public IEnumerable<string> Files {
+      get { return files; }
+    }
+
+    internal void AddFiles(IEnumerable<string> fileNames) {
+      files.AddRange(fileNames);
+    }
+
+    private List<IPluginDescription> dependencies = new List<IPluginDescription>();
+    /// <summary>
+    /// Gets all dependencies of the plugin.
+    /// </summary>
+    public IEnumerable<IPluginDescription> Dependencies {
+      get { return dependencies; }
+    }
+
+    public void AddDependency(PluginDescription dependency) {
+      dependencies.Add(dependency);
+    }
+
+
+    private List<string> assemblies = new List<string>();
+    /// <summary>
+    /// Gets the names of the assemblies that belong to this plugin.
+    /// </summary>
+    public IEnumerable<string> Assemblies {
+      get { return assemblies; }
+      // set { assemblies = value; }
+    }
+
+    internal void AddAssemblies(IEnumerable<string> assemblyNames) {
+      assemblies.AddRange(assemblyNames);
+    }
+
+    public PluginDescription() {
+      nTimesLoaded = 0;
+      pluginState = PluginState.Undefined;
+    }
+
+    /// <summary>
+    /// Gets the string representation of the plugin.
+    /// </summary>
+    /// <returns>The name of the plugin.</returns>
+    public override string ToString() {
+      return Name;
+    }
+
+    // equals and hashcode have to be implemented because we want to compare PluginDescriptions from 
+    // different AppDomains and serialization destroys reference equality
+    /// <summary>
+    /// Checks whether the given object is equal to the current plugin.
+    /// </summary>
+    /// <param name="obj">The object to compare.</param>
+    /// <returns><c>true</c> if it is equal, <c>false</c> otherwise.</returns>
+    public override bool Equals(object obj) {
+      if (!(obj is PluginDescription))
+        return false;
+      PluginDescription other = (PluginDescription)obj;
+
+      return other.Name == this.Name && other.Version == this.Version;
+    }
+    /// <summary>
+    /// Gets the hash code of the current plugin.
+    /// </summary>
+    /// <returns>The hash code of the plugin.</returns>
+    public override int GetHashCode() {
+      if (version != null) {
+        return name.GetHashCode() + version.GetHashCode();
+      } else return name.GetHashCode();
+    }
+  }
+}
Index: /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginInfrastructureEventArgs.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginInfrastructureEventArgs.cs	(revision 2503)
+++ /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginInfrastructureEventArgs.cs	(revision 2503)
@@ -0,0 +1,37 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace HeuristicLab.PluginInfrastructure.Manager {
+  // to be replaced by GenericEventArgs
+  [Serializable]
+  public class PluginInfrastructureEventArgs : EventArgs {
+    public string Action { get; private set; }
+    public object Entity { get; private set; }
+    public PluginInfrastructureEventArgs(string action, object entity) {
+      this.Action = action;
+      this.Entity = entity;
+    }
+  }
+}
Index: /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginManager.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginManager.cs	(revision 2503)
+++ /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginManager.cs	(revision 2503)
@@ -0,0 +1,168 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Security.Policy;
+using System.Reflection;
+using System.Diagnostics;
+using System.Security.Permissions;
+using System.Security;
+using System.Linq;
+
+namespace HeuristicLab.PluginInfrastructure.Manager {
+
+  // must extend MarshalByRefObject because of event passing between Loader and PluginManager (each in it's own AppDomain)
+  /// <summary>
+  /// Class to manage different plugins.
+  /// </summary>
+  public sealed class PluginManager : MarshalByRefObject {
+    /// <summary>
+    /// Event handler for actions in the plugin manager.
+    /// </summary>
+    public event EventHandler<PluginInfrastructureEventArgs> Action;
+
+    private string pluginDir;
+
+    private List<PluginDescription> plugins;
+
+    private List<ApplicationDescription> applications;
+    /// <summary>
+    /// Gets all installed applications.
+    /// </summary>
+    public IEnumerable<ApplicationDescription> Applications {
+      get { return applications; }
+    }
+
+    private object locker = new object();
+    private bool initialized;
+
+    public PluginManager(string pluginDir) {
+      this.pluginDir = pluginDir;
+      plugins = new List<PluginDescription>();
+      applications = new List<ApplicationDescription>();
+      Reset();
+    }
+
+    public void Reset() {
+      initialized = false;
+      if (plugins != null && plugins.Any(x => x.PluginState == PluginState.Loaded)) throw new InvalidOperationException("Reset() is not allowed while applications are active.");
+      plugins.Clear();
+      applications.Clear();
+    }
+
+    /// <summary>
+    /// Determines installed plugins and checks if all plugins are loadable.
+    /// </summary>
+    public void DiscoverAndCheckPlugins() {
+      OnAction(new PluginInfrastructureEventArgs("Initializing", "PluginInfrastructure"));
+      AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
+      setup.PrivateBinPath = pluginDir;
+      AppDomain pluginDomain = null;
+      try {
+        pluginDomain = AppDomain.CreateDomain("plugin domain", null, setup);
+        PluginValidator remoteValidator = (PluginValidator)pluginDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.Loader");
+        remoteValidator.PluginDir = pluginDir;
+        // forward all events from the remoteValidator to listeners
+        remoteValidator.PluginLoaded +=
+          delegate(object sender, PluginInfrastructureEventArgs e) {
+            OnAction(e);
+          };
+        // get list of plugins and applications from the validator
+        plugins.Clear(); applications.Clear();
+        plugins.AddRange(remoteValidator.Plugins);
+        applications.AddRange(remoteValidator.Applications);
+        OnAction(new PluginInfrastructureEventArgs("Initialized", "PluginInfrastructure"));
+      }
+      finally {
+        // discard the AppDomain that was used for plugin discovery
+        AppDomain.Unload(pluginDomain);
+        // unload all plugins
+        foreach (var pluginDescription in plugins)
+          pluginDescription.Unload();
+        initialized = true;
+      }
+    }
+
+
+    /// <summary>
+    /// Starts and application in a separate AppDomain.
+    /// Loads all enabled plugins and starts the application via a PluginRunner instance activated in the new AppDomain.
+    /// </summary>
+    /// <param name="appInfo">application to run</param>
+    public void Run(ApplicationDescription appInfo) {
+      if (!initialized) throw new InvalidOperationException("PluginManager is not initialized. DiscoverAndCheckPlugins() must be called before Run()");
+      // create a separate AppDomain for the application
+      // initialize the static ApplicationManager in the AppDomain
+      // and remotely tell it to start the application
+
+      OnAction(new PluginInfrastructureEventArgs("Starting application", appInfo));
+      AppDomain applicationDomain = null;
+      try {
+        AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
+        setup.PrivateBinPath = pluginDir;
+        applicationDomain = AppDomain.CreateDomain(appInfo.Name, null, setup);
+        DefaultApplicationManager applicationManager =
+          (DefaultApplicationManager)applicationDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.DefaultApplicationManager");
+        applicationManager.PluginLoaded += applicationManager_PluginLoaded;
+        applicationManager.PluginUnloaded += applicationManager_PluginUnloaded;
+        applicationManager.PrepareApplicationDomain(
+          new List<IApplicationDescription>(applications.Cast<IApplicationDescription>()),
+          new List<IPluginDescription>(plugins.Cast<IPluginDescription>()));
+        OnAction(new PluginInfrastructureEventArgs("Started application", appInfo));
+        applicationManager.Run(appInfo);
+      }
+      finally {
+        // make sure domain is unloaded in all cases
+        AppDomain.Unload(applicationDomain);
+      }
+    }
+
+    private void applicationManager_PluginUnloaded(object sender, PluginInfrastructureEventArgs e) {
+      // unload the matching plugin description (
+      PluginDescription desc = (PluginDescription)e.Entity;
+
+      // access to plugin descriptions has to be synchronized because multiple applications 
+      // can be started or stopped at the same time
+      lock (locker) {
+        plugins.First(x => x.Equals(desc)).Unload();
+      }
+      OnAction(new PluginInfrastructureEventArgs(e.Action, e.Entity));
+    }
+
+    private void applicationManager_PluginLoaded(object sender, PluginInfrastructureEventArgs e) {
+      // load the matching plugin description (
+      PluginDescription desc = (PluginDescription)e.Entity;
+      // access to plugin descriptions has to be synchronized because multiple applications 
+      // can be started or stopped at the same time
+      lock (locker) {
+        plugins.First(x => x.Equals(desc)).Load();
+      }
+      OnAction(new PluginInfrastructureEventArgs(e.Action, e.Entity));
+    }
+
+    private void OnAction(PluginInfrastructureEventArgs e) {
+      if (Action != null) {
+        Action(this, e);
+      }
+    }
+  }
+}
Index: /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginValidator.cs
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginValidator.cs	(revision 2503)
+++ /branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginValidator.cs	(revision 2503)
@@ -0,0 +1,322 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Reflection;
+using System.IO;
+using System.Diagnostics;
+using System.Linq;
+
+
+namespace HeuristicLab.PluginInfrastructure.Manager {
+  /// <summary>
+  /// Discovers all installed plugins in the plugin directory. Checks correctness of plugin meta-data and if
+  /// all plugin files are available and checks plugin dependencies. 
+  /// </summary>
+  internal sealed class PluginValidator : MarshalByRefObject {
+    internal event EventHandler<PluginInfrastructureEventArgs> PluginLoaded;
+
+    private Dictionary<PluginDescription, List<string>> pluginDependencies;
+
+    private List<ApplicationDescription> applications;
+    internal IEnumerable<ApplicationDescription> Applications {
+      get {
+        if (string.IsNullOrEmpty(PluginDir)) throw new InvalidOperationException("PluginDir is not set.");
+        if (applications == null) DiscoverAndCheckPlugins();
+        return applications;
+      }
+    }
+
+    private IEnumerable<PluginDescription> plugins;
+    internal IEnumerable<PluginDescription> Plugins {
+      get {
+        if (string.IsNullOrEmpty(PluginDir)) throw new InvalidOperationException("PluginDir is not set.");
+        if (plugins == null) DiscoverAndCheckPlugins();
+        return plugins;
+      }
+    }
+
+    public string PluginDir { get; set; }
+
+    public PluginValidator() {
+      this.pluginDependencies = new Dictionary<PluginDescription, List<string>>();
+
+      // ReflectionOnlyAssemblyResolveEvent must be handled because we load assemblies from the plugin path 
+      // (which is not listed in the default assembly lookup locations)
+      AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += ReflectionOnlyAssemblyResolveEventHandler;
+    }
+
+    private Assembly ReflectionOnlyAssemblyResolveEventHandler(object sender, ResolveEventArgs args) {
+      return Assembly.ReflectionOnlyLoad(args.Name);
+    }
+
+
+    /// <summary>
+    /// Init first clears all internal datastructures (including plugin lists)
+    /// 1. All assemblies in the plugins directory are loaded into the reflection only context.
+    /// 2. The validator checks if all necessary files for each plugin are available.
+    /// 3. The validator builds the tree of plugin descriptions (dependencies)
+    /// 4. The validator checks if all dependencies for each plugin are ok.
+    /// 5. All plugins for which there are no dependencies missing are loaded into the execution context.
+    /// 6. Each loaded plugin (all assemblies) is searched for a types that implement IPlugin
+    ///    then one instance of each IPlugin type is activated and the OnLoad hook is called.
+    /// 7. All types implementing IApplication are discovered
+    /// </summary>
+    internal void DiscoverAndCheckPlugins() {
+      pluginDependencies.Clear();
+
+      IEnumerable<Assembly> reflectionOnlyAssemblies = ReflectionOnlyLoadDlls();
+      IEnumerable<PluginDescription> pluginDescriptions = GatherPluginDescriptions(reflectionOnlyAssemblies);
+      CheckPluginFiles(pluginDescriptions);
+
+      // a full list of plugin descriptions is available now we can build the dependency tree
+      BuildDependencyTree(pluginDescriptions);
+
+      // recursively check if all necessary plugins are available and not disabled
+      // disable plugins with missing or disabled dependencies
+      CheckPluginDependencies(pluginDescriptions);
+
+      // mark all plugins as enabled that were not disabled in CheckPluginFiles or CheckPluginDependencies
+      foreach (var desc in pluginDescriptions)
+        if (desc.PluginState != PluginState.Disabled)
+          desc.Enable();
+
+      // test full loading (in contrast to reflection only loading) of plugins
+      // disables plugins that are not loaded correctly
+      LoadPlugins(pluginDescriptions);
+
+      plugins = pluginDescriptions;
+      DiscoverApplications();
+    }
+
+    private void DiscoverApplications() {
+      applications = new List<ApplicationDescription>();
+
+      foreach (IApplication application in GetApplications()) {
+        ApplicationDescription info = new ApplicationDescription();
+        info.Name = application.Name;
+        info.Version = application.Version;
+        info.Description = application.Description;
+        info.AutoRestart = application.RestartOnErrors;
+        info.DeclaringAssemblyName = application.GetType().Assembly.GetName().Name;
+        info.DeclaringTypeName = application.GetType().Namespace + "." + application.GetType().Name;
+
+        applications.Add(info);
+      }
+    }
+
+    private IEnumerable<IApplication> GetApplications() {
+      return from asm in AppDomain.CurrentDomain.GetAssemblies()
+             from t in asm.GetTypes()
+             where typeof(IApplication).IsAssignableFrom(t) &&
+               !t.IsAbstract && !t.IsInterface && !t.HasElementType
+             select (IApplication)Activator.CreateInstance(t);
+    }
+
+    private IEnumerable<Assembly> ReflectionOnlyLoadDlls() {
+      List<Assembly> assemblies = new List<Assembly>();
+      // try to load each .dll file in the plugin directory into the reflection only context
+      foreach (string filename in Directory.GetFiles(PluginDir, "*.dll")) {
+        try {
+          assemblies.Add(Assembly.ReflectionOnlyLoadFrom(filename));
+        }
+        catch (BadImageFormatException) { } // just ignore the case that the .dll file is not a CLR assembly (e.g. a native dll)
+      }
+      return assemblies;
+    }
+
+    // find all types implementing IPlugin in the reflectionOnlyAssemblies and create a list of plugin descriptions
+    // the dependencies in the plugin descriptions are not yet set correctly because we need to create
+    // the full list of all plugin descriptions first
+    private IEnumerable<PluginDescription> GatherPluginDescriptions(IEnumerable<Assembly> assemblies) {
+      List<PluginDescription> pluginDescriptions = new List<PluginDescription>();
+      foreach (Assembly assembly in assemblies) {
+        // GetExportedTypes throws FileNotFoundException when a referenced assembly
+        // of the current assembly is missing.
+        try {
+          foreach (Type t in assembly.GetExportedTypes()) {
+            // if there is a type that implements IPlugin
+            // use AssemblyQualifiedName to compare the types because we can't directly 
+            // compare ReflectionOnly types and Execution types
+            if (!t.IsAbstract &&
+                t.GetInterfaces().Any(x => x.AssemblyQualifiedName == typeof(IPlugin).AssemblyQualifiedName)) {
+              // fetch the attributes of the IPlugin type
+              pluginDescriptions.Add(GetPluginDescription(t));
+            }
+          }
+        }
+        // ignore exceptions. Just don't yield a plugin description when an exception is thrown
+        catch (FileNotFoundException) {
+        }
+        catch (FileLoadException) {
+        }
+        catch (InvalidPluginException) {
+        }
+      }
+      return pluginDescriptions;
+    }
+
+    /// <summary>
+    /// Extracts plugin information for this type.
+    /// Reads plugin name, list and type of files and dependencies of the plugin. This information is necessary for
+    /// plugin dependency checking before plugin activation.
+    /// </summary>
+    /// <param name="t"></param>
+    private PluginDescription GetPluginDescription(Type pluginType) {
+      // get all attributes of that type
+      IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(pluginType);
+      List<string> pluginAssemblies = new List<string>();
+      List<string> pluginDependencies = new List<string>();
+      List<string> pluginFiles = new List<string>();
+      string pluginName = null;
+      // iterate through all custom attributes and search for attributed that we are interested in 
+      foreach (CustomAttributeData attributeData in attributes) {
+        if (IsAttributeDataForType(attributeData, typeof(PluginAttribute))) {
+          pluginName = (string)attributeData.ConstructorArguments[0].Value;
+        } else if (IsAttributeDataForType(attributeData, typeof(PluginDependencyAttribute))) {
+          pluginDependencies.Add((string)attributeData.ConstructorArguments[0].Value);
+        } else if (IsAttributeDataForType(attributeData, typeof(PluginFileAttribute))) {
+          string pluginFileName = (string)attributeData.ConstructorArguments[0].Value;
+          PluginFileType fileType = (PluginFileType)attributeData.ConstructorArguments[1].Value;
+          pluginFiles.Add(Path.Combine(PluginDir, pluginFileName));
+          if (fileType == PluginFileType.Assembly) {
+            pluginAssemblies.Add(Path.Combine(PluginDir, pluginFileName));
+          }
+        }
+      }
+
+      // minimal sanity check of the attribute values
+      if (!string.IsNullOrEmpty(pluginName) &&
+          pluginFiles.Count > 0 &&
+          pluginAssemblies.Count > 0) {
+        // create a temporary PluginDescription that contains the attribute values
+        PluginDescription info = new PluginDescription();
+        info.Name = pluginName;
+        info.Version = pluginType.Assembly.GetName().Version;
+        info.AddAssemblies(pluginAssemblies);
+        info.AddFiles(pluginFiles);
+
+        this.pluginDependencies[info] = pluginDependencies;
+        return info;
+      } else {
+        throw new InvalidPluginException("Invalid metadata in plugin " + pluginType.ToString());
+      }
+    }
+
+    private bool IsAttributeDataForType(CustomAttributeData attributeData, Type attributeType) {
+      return attributeData.Constructor.DeclaringType.AssemblyQualifiedName == attributeType.AssemblyQualifiedName;
+    }
+
+    // builds a dependency tree of all plugin descriptions
+    // searches matching plugin descriptions based on the list of dependency names for each plugin
+    // and sets the dependencies in the plugin descriptions
+    private void BuildDependencyTree(IEnumerable<PluginDescription> pluginDescriptions) {
+      foreach (var desc in pluginDescriptions) {
+        foreach (string pluginName in pluginDependencies[desc]) {
+          var matchingDescriptions = pluginDescriptions.Where(x => x.Name == pluginName);
+          if (matchingDescriptions.Count() > 0) {
+            desc.AddDependency(matchingDescriptions.First());
+          } else {
+            // no plugin description that matches the dependency name is available => plugin is disabled
+            desc.Disable();
+            break; // stop processing more dependencies
+          }
+        }
+      }
+    }
+
+    private void CheckPluginDependencies(IEnumerable<PluginDescription> pluginDescriptions) {
+      foreach (PluginDescription pluginDescription in pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled)) {
+        if (IsAnyDependencyDisabled(pluginDescription)) {
+          pluginDescription.Disable();
+        }
+      }
+    }
+
+
+    private bool IsAnyDependencyDisabled(PluginDescription descr) {
+      if (descr.PluginState == PluginState.Disabled) return true;
+      foreach (PluginDescription dependency in descr.Dependencies) {
+        if (IsAnyDependencyDisabled(dependency)) return true;
+      }
+      return false;
+    }
+
+    private void LoadPlugins(IEnumerable<PluginDescription> pluginDescriptions) {
+      // load all loadable plugins (all dependencies available) into the execution context
+      foreach (var desc in PluginDescriptionIterator.IterateInDependencyOrder(pluginDescriptions
+                                                                                .Cast<IPluginDescription>()
+                                                                                .Where(x => x.PluginState != PluginState.Disabled))) {
+        List<Type> types = new List<Type>();
+        foreach (string assembly in desc.Assemblies) {
+          var asm = Assembly.LoadFrom(assembly);
+          foreach (Type t in asm.GetTypes()) {
+            if (typeof(IPlugin).IsAssignableFrom(t)) {
+              types.Add(t);
+            }
+          }
+        }
+
+        foreach (Type pluginType in types) {
+          if (!pluginType.IsAbstract && !pluginType.IsInterface && !pluginType.HasElementType) {
+            IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType);
+            plugin.OnLoad();
+            OnPluginLoaded(new PluginInfrastructureEventArgs("Plugin loaded", plugin.Name));
+          }
+        }
+        desc.Load();
+      }
+    }
+
+    // checks if all declared plugin files are actually available and disables plugins with missing files
+    private void CheckPluginFiles(IEnumerable<PluginDescription> pluginDescriptions) {
+      foreach (PluginDescription desc in pluginDescriptions) {
+        if (!CheckPluginFiles(desc)) {
+          desc.Disable();
+        }
+      }
+    }
+
+    private bool CheckPluginFiles(PluginDescription PluginDescription) {
+      foreach (string filename in PluginDescription.Files) {
+        if (!File.Exists(filename)) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    internal void OnPluginLoaded(PluginInfrastructureEventArgs e) {
+      if (PluginLoaded != null)
+        PluginLoaded(this, e);
+    }
+
+    /// <summary>
+    /// Initializes the life time service with an infinite lease time.
+    /// </summary>
+    /// <returns><c>null</c>.</returns>
+    public override object InitializeLifetimeService() {
+      return null;
+    }
+  }
+}
Index: /branches/PluginInfrastructure Refactoring/HeuristicLab/HeuristicLab.csproj
===================================================================
--- /branches/PluginInfrastructure Refactoring/HeuristicLab/HeuristicLab.csproj	(revision 2502)
+++ /branches/PluginInfrastructure Refactoring/HeuristicLab/HeuristicLab.csproj	(revision 2503)
@@ -127,8 +127,4 @@
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\HeuristicLab.PluginInfrastructure.Manager\HeuristicLab.PluginInfrastructure.Manager.csproj">
-      <Project>{CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}</Project>
-      <Name>HeuristicLab.PluginInfrastructure.Manager</Name>
-    </ProjectReference>
     <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj">
       <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
