Index: branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.GUI/HeuristicLab.PluginInfrastructure.GUI.csproj
===================================================================
--- branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.GUI/HeuristicLab.PluginInfrastructure.GUI.csproj	(revision 2496)
+++ branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.GUI/HeuristicLab.PluginInfrastructure.GUI.csproj	(revision 2497)
@@ -110,5 +110,4 @@
     </Compile>
     <Compile Include="PluginAction.cs" />
-    <Compile Include="PluginDescription.cs" />
     <Compile Include="PluginNameTransform.cs" />
     <Compile Include="PluginSource.cs" />
Index: branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/ApplicationDescription.cs
===================================================================
--- branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/ApplicationDescription.cs	(revision 2496)
+++ branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/ApplicationDescription.cs	(revision 2497)
@@ -84,4 +84,8 @@
       set { declaringTypeName = value; }
     }
+
+    public override string ToString() {
+      return Name;
+    }
   }
 }
Index: branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/ApplicationManager.cs
===================================================================
--- branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/ApplicationManager.cs	(revision 2496)
+++ 	(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; }
-    }
-
-    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(plugin.Name);
-          }
-        }
-        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(string name) {
-      if (PluginLoaded != null) PluginLoaded(this, new PluginInfrastructureEventArgs("Plugin loaded", name));
-    }
-
-    // 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/DefaultApplicationManager.cs
===================================================================
--- branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/DefaultApplicationManager.cs	(revision 2497)
+++ branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/DefaultApplicationManager.cs	(revision 2497)
@@ -0,0 +1,219 @@
+#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 2496)
+++ branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/HeuristicLab.PluginInfrastructure.Manager.csproj	(revision 2497)
@@ -49,7 +49,5 @@
   <ItemGroup>
     <Compile Include="ApplicationDescription.cs" />
-    <Compile Include="ApplicationManager.cs">
-      <SubType>Code</SubType>
-    </Compile>
+    <Compile Include="DefaultApplicationManager.cs" />
     <Compile Include="Loader.cs" />
     <Compile Include="PluginDescription.cs" />
Index: branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Loader.cs
===================================================================
--- branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Loader.cs	(revision 2496)
+++ branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Loader.cs	(revision 2497)
@@ -38,4 +38,5 @@
     internal IEnumerable<ApplicationDescription> Applications {
       get {
+        if (applications == null) DiscoverAndCheckPlugins();
         return applications;
       }
@@ -45,4 +46,5 @@
     internal IEnumerable<PluginDescription> Plugins {
       get {
+        if (plugins == null) DiscoverAndCheckPlugins();
         return plugins;
       }
@@ -52,18 +54,13 @@
 
     public Loader() {
-      this.applications = new List<ApplicationDescription>();
-      this.plugins = new List<PluginDescription>();
       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) {
-      //try {
       return Assembly.ReflectionOnlyLoad(args.Name);
-      //}
-      //catch (FileLoadException ex) {
-      //  return null;
-      //}
     }
 
@@ -80,5 +77,5 @@
     /// 7. All types implementing IApplication are discovered
     /// </summary>
-    internal void Init() {
+    private void DiscoverAndCheckPlugins() {
       pluginDependencies.Clear();
 
@@ -163,4 +160,5 @@
           }
         }
+        // ignore exceptions. Just don't yield a plugin description when an exception is thrown
         catch (FileNotFoundException) {
         }
@@ -310,5 +308,5 @@
 
     /// <summary>
-    /// Initializes the life time service with an infinte lease time.
+    /// Initializes the life time service with an infinite lease time.
     /// </summary>
     /// <returns><c>null</c>.</returns>
Index: branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginDescription.cs
===================================================================
--- branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginDescription.cs	(revision 2496)
+++ branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginDescription.cs	(revision 2497)
@@ -135,14 +135,4 @@
     }
 
-
-    //private string message;
-    ///// <summary>
-    ///// Gets or sets the message.
-    ///// </summary>
-    //public string Message {
-    //  get { return message; }
-    //  set { message = value; }
-    //}
-
     /// <summary>
     /// Gets the string representation of the plugin.
@@ -153,27 +143,27 @@
     }
 
-    //// 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;
+    // 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();
-    //}
+      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.Manager/PluginInfrastructureEventArgs.cs
===================================================================
--- branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginInfrastructureEventArgs.cs	(revision 2496)
+++ branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginInfrastructureEventArgs.cs	(revision 2497)
@@ -29,8 +29,8 @@
   public class PluginInfrastructureEventArgs : EventArgs {
     public string Action { get; private set; }
-    public string EntityName { get; private set; }
-    public PluginInfrastructureEventArgs(string action, string entityName) {
-      Action = action;
-      EntityName = entityName;
+    public object Entity { get; private set; }
+    public PluginInfrastructureEventArgs(string action, object entity) {
+      this.Action = action;
+      this.Entity = entity;
     }
   }
Index: branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginManager.cs
===================================================================
--- branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginManager.cs	(revision 2496)
+++ branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginManager.cs	(revision 2497)
@@ -43,46 +43,9 @@
     private string pluginDir;
 
-    // singleton pattern
     public PluginManager(string pluginDir) {
       this.pluginDir = pluginDir;
     }
 
-    ///// <summary>
-    ///// Gets all installed plugins.
-    ///// </summary>
-    ///// <remarks>This information is provided by a <see cref="Loader"/>.</remarks>
-    //public ICollection<PluginInfo> InstalledPlugins {
-    //  get { return remoteLoader.InstalledPlugins; }
-    //}
-
-    ///// <summary>
-    ///// Gets all disabled plugins.
-    ///// </summary>
-    ///// <remarks>This information is provided by a <see cref="Loader"/>.</remarks>
-    //public ICollection<PluginInfo> DisabledPlugins {
-    //  get { return remoteLoader.DisabledPlugins; }
-    //}
-
-    ///// <summary>
-    ///// Gets all active plugins.
-    ///// </summary>
-    ///// <remarks>This information is provided by a <see cref="Loader"/>.</remarks>
-    //public ICollection<PluginInfo> ActivePlugins {
-    //  get { return remoteLoader.ActivePlugins; }
-    //}
-
-    //private ICollection<PluginInfo> loadedPlugins;
-    ///// <summary>
-    ///// Gets or (internally) sets the loaded plugins.
-    ///// </summary>
-    //public ICollection<PluginInfo> LoadedPlugins {
-    //  get { return loadedPlugins; }
-    //  internal set { loadedPlugins = value; }
-    //}
-
     private List<PluginDescription> plugins;
-    //public IEnumerable<PluginDescription> Plugins {
-    //  get { return plugins; }
-    //}
 
     private List<ApplicationDescription> applications;
@@ -97,40 +60,25 @@
     /// Determines installed plugins and checks if all plugins are loadable.
     /// </summary>
-    public void Initialize() {
-      NotifyListeners("Initializing", "PluginInfrastructure");
+    public void DiscoverAndCheckPlugins() {
+      FireAction("Initializing", "PluginInfrastructure");
       AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
       setup.PrivateBinPath = pluginDir;
-      AppDomain pluginDomain = AppDomain.CreateDomain("plugin domain", null, setup);
-      Loader remoteLoader = (Loader)pluginDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.Loader");
-      remoteLoader.PluginDir = pluginDir;
-      remoteLoader.PluginLoaded += delegate(object sender, PluginInfrastructureEventArgs args) { NotifyListeners(args.Action, args.EntityName); }; // forward all events from the remoteLoader to listeners
-      remoteLoader.Init();
-      NotifyListeners("Initialized", "PluginInfrastructure");
-
-      plugins = new List<PluginDescription>(remoteLoader.Plugins);
-      applications = new List<ApplicationDescription>(remoteLoader.Applications);
-
-      // discard the AppDomain that was used for plugin discovery
-      UnloadAppDomain(pluginDomain);
+      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);
+      }
     }
 
-    private void UnloadAppDomain(AppDomain appDomain) {
-      AppDomain.Unload(appDomain);
-
-      // set all loaded plugins back to enabled
-      foreach (var pluginDescription in plugins)
-        pluginDescription.Unload();
-    }
-
-
-    ///// <summary>
-    ///// Creates a new AppDomain with all plugins preloaded.
-    ///// </summary>
-    ///// <param name="friendlyName">Name of the new AppDomain</param>
-    ///// <returns>the new AppDomain with all plugins preloaded.</returns>
-    //public AppDomain CreateAndInitAppDomain(string friendlyName) {
-
-    //  return applicationDomain;
-    //}
 
     /// <summary>
@@ -144,5 +92,5 @@
       // and remotely tell it to start the application
 
-      NotifyListeners("Starting application", appInfo.Name);
+      FireAction("Starting application", appInfo.Name);
       AppDomain applicationDomain = null;
       try {
@@ -152,114 +100,39 @@
         DefaultApplicationManager applicationManager =
           (DefaultApplicationManager)applicationDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.DefaultApplicationManager");
-        applicationManager.PluginLoaded += delegate(object sender, PluginInfrastructureEventArgs args) { NotifyListeners(args.Action, args.EntityName); };
+        applicationManager.PluginLoaded += applicationManager_PluginLoaded;
         applicationManager.PrepareApplicationDomain(
           new List<IApplicationDescription>(applications.Cast<IApplicationDescription>()),
           new List<IPluginDescription>(plugins.Cast<IPluginDescription>()));
-        NotifyListeners("Started application", appInfo.Name);
+        FireAction("Started application", appInfo.Name);
         applicationManager.Run(appInfo);
       }
       finally {
         // make sure domain is unloaded in all cases
-        if (applicationDomain != null) AppDomain.Unload(applicationDomain);
+        UnloadAppDomain(applicationDomain);
       }
     }
 
-    ///// <summary>
-    ///// Creates a new AppDomain with all plugins preloaded and Sandboxing capability.
-    ///// </summary>
-    ///// <param name="assembly">Assembly reference</param>
-    ///// <returns>the strongname of the assembly</returns>
-    //private StrongName CreateStrongName(Assembly assembly) {
-    //  if (assembly == null)
-    //    throw new ArgumentNullException("assembly");
+    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);
+    }
 
-    //  AssemblyName assemblyName = assembly.GetName();
-    //  Debug.Assert(assemblyName != null, "Could not get assembly name");
+    private void UnloadAppDomain(AppDomain appDomain) {
+      AppDomain.Unload(appDomain);
 
-    //  // get the public key blob
-    //  byte[] publicKey = assemblyName.GetPublicKey();
-    //  if (publicKey == null || publicKey.Length == 0)
-    //    throw new InvalidOperationException("Assembly is not strongly named");
+      // TODO: Update plugin descriptions in all active AppDomains
 
-    //  StrongNamePublicKeyBlob keyBlob = new StrongNamePublicKeyBlob(publicKey);
+      // unload all plugins
+      foreach (var pluginDescription in plugins)
+        pluginDescription.Unload();
+    }
 
-    //  // and create the StrongName
-    //  return new StrongName(keyBlob, assemblyName.Name, assemblyName.Version);
-    //}
-
-    //public AppDomain CreateAndInitAppDomainWithSandbox(string friendlyName, bool sandboxed, Type jobType, ICollection<byte[]> assemblyFiles) {
-    //  PermissionSet pset;
-
-
-
-    //  //DiscoveryService dService = new DiscoveryService();
-    //  //get the declaring plugin of the job
-    //  //PluginInfo jobPlugin = dService.GetDeclaringPlugin(jobType);
-
-    //  //get all the plugins that have dependencies with the jobplugin
-    //  //List<PluginInfo> depPlugins = GetDependentPluginsRec(jobPlugin);
-    //  //insert all jobs into one list
-    //  //depPlugins.Add(jobPlugin);
-
-    //  if (sandboxed) {
-    //    pset = new PermissionSet(PermissionState.None);
-    //    pset.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
-    //    pset.AddPermission(new ReflectionPermission(PermissionState.Unrestricted));
-    //    FileIOPermission fPerm = new FileIOPermission(PermissionState.None);
-
-    //    /*foreach (PluginInfo plugin in depPlugins) {
-    //        foreach(String assemblies in plugin.Assemblies)
-    //          fPerm.AddPathList(FileIOPermissionAccess.AllAccess, assemblies);
-    //    }
-
-    //    pset.AddPermission(fPerm);*/
-
-    //  } else {
-    //    pset = new PermissionSet(PermissionState.Unrestricted);
-    //  }
-    //  AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
-    //  setup.PrivateBinPath = pluginDir;
-    //  setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
-    //  AppDomain applicationDomain = AppDomain.CreateDomain(friendlyName, AppDomain.CurrentDomain.Evidence, setup, pset, CreateStrongName(Assembly.GetExecutingAssembly()));
-    //  Runner remoteRunner = (Runner)applicationDomain.CreateInstanceAndUnwrap(typeof(Runner).Assembly.GetName().Name, typeof(Runner).FullName);
-    //  NotifyListeners("Initializing", "All plugins");
-
-    //  if (assemblyFiles != null && assemblyFiles.Count > 0)
-    //    remoteRunner.LoadAssemblies(assemblyFiles);
-
-    //  //if (depPlugins != null && depPlugins.Count > 0) {        
-    //  //remoteRunner.LoadPlugins(ActivePlugins);
-    //  //}
-    //  NotifyListeners("Initialized", "All plugins");
-    //  return applicationDomain;
-    //}
-
-    ///// <summary>
-    ///// Calculates a set of plugins that directly or transitively depend on the plugin given in the argument.
-    ///// </summary>
-    ///// <param name="pluginInfo">The plugin the other depend on.</param>
-    ///// <returns>a list of plugins that are directly of transitively dependent.</returns>
-    //public List<PluginDescription> GetDependentPlugins(PluginDescription pluginInfo) {
-    //  List<PluginDescription> mergedList = new List<PluginDescription>();
-    //  foreach (PluginDescription plugin in Plugins) {
-    //    if (plugin.Dependencies.Contains(pluginInfo)) {
-    //      if (!mergedList.Contains(plugin)) {
-    //        mergedList.Add(plugin);
-    //      }
-    //      // for each of the dependent plugins add the list of transitively dependent plugins
-    //      // make sure that only one entry for each plugin is added to the merged list
-    //      foreach (PluginDescription dependentPlugin in GetDependentPlugins(plugin)) {
-    //        if (!mergedList.Contains(dependentPlugin)) {
-    //          mergedList.Add(dependentPlugin);
-    //        }
-    //      }
-    //    }
-    //  }
-    //  return mergedList;
-    //}
-
-    private void NotifyListeners(string action, string entityName) {
+    private void FireAction(string action, object entity) {
       if (Action != null) {
-        Action(this, new PluginInfrastructureEventArgs(action, entityName));
+        Action(this, new PluginInfrastructureEventArgs(action, entity));
       }
     }
Index: branches/PluginInfrastructure Refactoring/HeuristicLab/MainForm.cs
===================================================================
--- branches/PluginInfrastructure Refactoring/HeuristicLab/MainForm.cs	(revision 2496)
+++ branches/PluginInfrastructure Refactoring/HeuristicLab/MainForm.cs	(revision 2497)
@@ -54,5 +54,5 @@
       this.Enabled = false;
 
-      pluginManager.Initialize();
+      pluginManager.DiscoverAndCheckPlugins();
 
       applicationsListView.Items.Clear();
Index: branches/PluginInfrastructure Refactoring/HeuristicLab/SplashScreen.cs
===================================================================
--- branches/PluginInfrastructure Refactoring/HeuristicLab/SplashScreen.cs	(revision 2496)
+++ branches/PluginInfrastructure Refactoring/HeuristicLab/SplashScreen.cs	(revision 2497)
@@ -89,5 +89,5 @@
 
     public void managerActionEventHandler(object sender, PluginInfrastructureEventArgs e) {
-      string info = e.Action + ": " + e.EntityName;
+      string info = e.Action + ": " + e.Entity;
       //if (e.Action == PluginManagerAction.Initializing) info = "Initializing ...";
       //else if (e.Action == PluginManagerAction.PluginLoaded) info = "Loaded plugin " + e.Id + " ...";
