Index: trunk/sources/HeuristicLab.PluginInfrastructure/3.3/HeuristicLab.PluginInfrastructure-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.PluginInfrastructure/3.3/HeuristicLab.PluginInfrastructure-3.3.csproj	(revision 8563)
+++ trunk/sources/HeuristicLab.PluginInfrastructure/3.3/HeuristicLab.PluginInfrastructure-3.3.csproj	(revision 8571)
@@ -272,4 +272,5 @@
     <Compile Include="Main.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TypeExtensions.cs" />
     <None Include="Advanced\DeploymentService\GenerateServiceClients.cmd" />
     <None Include="app.config">
Index: trunk/sources/HeuristicLab.PluginInfrastructure/3.3/LightweightApplicationManager.cs
===================================================================
--- trunk/sources/HeuristicLab.PluginInfrastructure/3.3/LightweightApplicationManager.cs	(revision 8563)
+++ trunk/sources/HeuristicLab.PluginInfrastructure/3.3/LightweightApplicationManager.cs	(revision 8571)
@@ -75,5 +75,6 @@
       foreach (Type t in GetTypes(type)) {
         object instance = null;
-        try { instance = Activator.CreateInstance(t); } catch { }
+        try { instance = Activator.CreateInstance(t); }
+        catch { }
         if (instance != null) instances.Add(instance);
       }
@@ -127,59 +128,21 @@
         var assemblyTypes = assembly.GetTypes();
 
-        var buildTypes = from t in assembly.GetTypes()
-                         where CheckTypeCompatibility(type, t)
-                         where !IsNonDiscoverableType(t)
-                         where onlyInstantiable == false ||
-                               (!t.IsAbstract && !t.IsInterface && !t.HasElementType)
-                         select BuildType(t, type);
+        var matchingTypes = from assemblyType in assembly.GetTypes()
+                            let t = assemblyType.BuildType(type)
+                            where t != null
+                            where t.IsSubTypeOf(type)
+                            where !t.IsNonDiscoverableType()
+                            where onlyInstantiable == false || (!t.IsAbstract && !t.IsInterface && !t.HasElementType)
+                            where includeGenericTypeDefinitions || !t.IsGenericTypeDefinition
+                            select t;
 
-        return from t in buildTypes
-               where includeGenericTypeDefinitions || !t.IsGenericTypeDefinition
-               select t;
-      } catch (TypeLoadException) {
-        return Enumerable.Empty<Type>();
-      } catch (ReflectionTypeLoadException) {
+        return matchingTypes;
+      }
+      catch (TypeLoadException) {
         return Enumerable.Empty<Type>();
       }
-    }
-
-    private static bool IsNonDiscoverableType(Type t) {
-      return t.GetCustomAttributes(typeof(NonDiscoverableTypeAttribute), false).Any();
-    }
-
-    private static bool CheckTypeCompatibility(Type type, Type other) {
-      if (type.IsAssignableFrom(other))
-        return true;
-      if (type.IsGenericType && other.IsGenericType) {
-        var otherGenericArguments = other.GetGenericArguments();
-        var typeGenericArguments = type.GetGenericArguments();
-
-        //check type arguments count
-        if (otherGenericArguments.Length != typeGenericArguments.Length)
-          return false;
-
-        //check type arguments & constraints
-        int i = 0;
-        foreach (var genericArgument in typeGenericArguments) {
-          if (otherGenericArguments[i].IsGenericParameter) {
-            foreach (var constraint in otherGenericArguments[i].GetGenericParameterConstraints())
-              if (!constraint.IsAssignableFrom(genericArgument)) return false;
-          } else if (genericArgument != otherGenericArguments[i]) return false;
-          i++;
-        }
-        //check types
-        try {
-          var otherGenericTypeDefinition = other.GetGenericTypeDefinition();
-          if (type.IsAssignableFrom(otherGenericTypeDefinition.MakeGenericType(typeGenericArguments)))
-            return true;
-        } catch (Exception) { }
+      catch (ReflectionTypeLoadException) {
+        return Enumerable.Empty<Type>();
       }
-      return false;
-    }
-    private static Type BuildType(Type type, Type protoType) {
-      if (type.IsGenericType && protoType.IsGenericType)
-        return type.GetGenericTypeDefinition().MakeGenericType(protoType.GetGenericArguments());
-      else
-        return type;
     }
 
Index: trunk/sources/HeuristicLab.PluginInfrastructure/3.3/SandboxApplicationManager.cs
===================================================================
--- trunk/sources/HeuristicLab.PluginInfrastructure/3.3/SandboxApplicationManager.cs	(revision 8563)
+++ trunk/sources/HeuristicLab.PluginInfrastructure/3.3/SandboxApplicationManager.cs	(revision 8571)
@@ -261,56 +261,14 @@
     /// <returns>Enumerable of the discovered types.</returns>
     private static IEnumerable<Type> GetTypes(Type type, Assembly assembly, bool onlyInstantiable, bool includeGenericTypeDefinitions) {
-      var buildTypes = from t in assembly.GetTypes()
-                       where CheckTypeCompatibility(type, t)
-                       where !IsNonDiscoverableType(t)
-                       where onlyInstantiable == false ||
-                             (!t.IsAbstract && !t.IsInterface && !t.HasElementType)
-                       select BuildType(t, type);
-
-      return from t in buildTypes
-             where includeGenericTypeDefinitions || !t.IsGenericTypeDefinition
-             select t;
-    }
-
-
-    private static bool IsNonDiscoverableType(Type t) {
-      return t.GetCustomAttributes(typeof(NonDiscoverableTypeAttribute), false).Any();
-    }
-
-    private static bool CheckTypeCompatibility(Type type, Type other) {
-      if (type.IsAssignableFrom(other))
-        return true;
-      if (type.IsGenericType && other.IsGenericType) {
-        var otherGenericArguments = other.GetGenericArguments();
-        var typeGenericArguments = type.GetGenericArguments();
-
-        //check type arguments count
-        if (otherGenericArguments.Length != typeGenericArguments.Length)
-          return false;
-
-        //check type arguments & constraints
-        int i = 0;
-        foreach (var genericArgument in typeGenericArguments) {
-          if (otherGenericArguments[i].IsGenericParameter) {
-            foreach (var constraint in otherGenericArguments[i].GetGenericParameterConstraints())
-              if (!constraint.IsAssignableFrom(genericArgument)) return false;
-          } else if (genericArgument != otherGenericArguments[i]) return false;
-          i++;
-        }
-        //check types
-        try {
-          var otherGenericTypeDefinition = other.GetGenericTypeDefinition();
-          if (type.IsAssignableFrom(otherGenericTypeDefinition.MakeGenericType(typeGenericArguments)))
-            return true;
-        }
-        catch (Exception) { }
-      }
-      return false;
-    }
-    private static Type BuildType(Type type, Type protoType) {
-      if (type.IsGenericType && protoType.IsGenericType)
-        return type.GetGenericTypeDefinition().MakeGenericType(protoType.GetGenericArguments());
-      else
-        return type;
+      var matchingTypes = from assemblyType in assembly.GetTypes()
+                          let t = assemblyType.BuildType(type)
+                          where t != null
+                          where t.IsSubTypeOf(type)
+                          where !t.IsNonDiscoverableType()
+                          where onlyInstantiable == false || (!t.IsAbstract && !t.IsInterface && !t.HasElementType)
+                          where includeGenericTypeDefinitions || !t.IsGenericTypeDefinition
+                          select t;
+
+      return matchingTypes;
     }
 
Index: trunk/sources/HeuristicLab.PluginInfrastructure/3.3/TypeExtensions.cs
===================================================================
--- trunk/sources/HeuristicLab.PluginInfrastructure/3.3/TypeExtensions.cs	(revision 8571)
+++ trunk/sources/HeuristicLab.PluginInfrastructure/3.3/TypeExtensions.cs	(revision 8571)
@@ -0,0 +1,129 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Linq;
+using System.Reflection;
+
+namespace HeuristicLab.PluginInfrastructure {
+  internal static class TypeExtensions {
+    internal static bool IsNonDiscoverableType(this Type t) {
+      return t.GetCustomAttributes(typeof(NonDiscoverableTypeAttribute), false).Any();
+    }
+
+    /// <summary>
+    /// Constructs a concrete type from a given proto type.
+    /// </summary>
+    /// <param name="type"></param>
+    /// <param name="protoType"></param>
+    /// <returns>The constructed type, a generic type definition or null, if a type construction is not possible</returns>
+    /// <remarks>This method does not work with nested generic types</remarks>
+    internal static Type BuildType(this Type type, Type protoType) {
+      if (type == null || protoType == null) throw new ArgumentNullException();
+
+      if (!type.IsGenericTypeDefinition) return type;
+      if (protoType.IsGenericTypeDefinition) return type;
+      if (!protoType.IsGenericType) return type;
+
+      var typeGenericArguments = type.GetGenericArguments();
+      var protoTypeGenericArguments = protoType.GetGenericArguments();
+      if (typeGenericArguments.Length != protoTypeGenericArguments.Length) return null;
+
+      for (int i = 0; i < typeGenericArguments.Length; i++) {
+        var typeGenericArgument = typeGenericArguments[i];
+        var protoTypeGenericArgument = protoTypeGenericArguments[i];
+
+        //check class contraint on generic type parameter 
+        if (typeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint))
+          if (!protoTypeGenericArgument.IsClass && !protoTypeGenericArgument.IsInterface && !protoType.IsArray) return null;
+
+        //check default constructor constraint on generic type parameter 
+        if (typeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint))
+          if (!protoTypeGenericArgument.IsValueType && protoTypeGenericArgument.GetConstructor(Type.EmptyTypes) == null) return null;
+
+        //check type restrictions on generic type parameter
+        foreach (var constraint in typeGenericArgument.GetGenericParameterConstraints())
+          if (!constraint.IsAssignableFrom(protoTypeGenericArgument)) return null;
+      }
+
+      try {
+        return type.MakeGenericType(protoTypeGenericArguments);
+      }
+      catch (Exception) {
+        return null;
+      }
+    }
+
+    internal static bool IsSubTypeOf(this Type subType, Type baseType) {
+      if (baseType.IsAssignableFrom(subType)) return true;
+      if (!baseType.IsGenericType) return false;
+
+      if (RecursiveCheckGenericTypes(baseType, subType)) return true;
+      IEnumerable<Type> implementedInterfaces = subType.GetInterfaces().Where(t => t.IsGenericType);
+      foreach (var implementedInterface in implementedInterfaces.Where(i => i.IsGenericType)) {
+        if (baseType.CheckGenericTypes(implementedInterface)) return true;
+      }
+
+      return false;
+    }
+
+    private static bool RecursiveCheckGenericTypes(Type baseType, Type subType) {
+      if (!baseType.IsGenericType) return false;
+      if (!subType.IsGenericType) return false;
+      if (baseType.CheckGenericTypes(subType)) return true;
+      if (subType.BaseType == null) return false;
+
+      return RecursiveCheckGenericTypes(baseType, subType.BaseType);
+    }
+
+    private static bool CheckGenericTypes(this Type baseType, Type subType) {
+      var baseTypeGenericTypeDefinition = baseType.GetGenericTypeDefinition();
+      var subTypeGenericTypeDefinition = subType.GetGenericTypeDefinition();
+      if (baseTypeGenericTypeDefinition != subTypeGenericTypeDefinition) return false;
+      var baseTypeGenericArguments = baseType.GetGenericArguments();
+      var subTypeGenericArguments = subType.GetGenericArguments();
+
+      for (int i = 0; i < baseTypeGenericArguments.Length; i++) {
+        var baseTypeGenericArgument = baseTypeGenericArguments[i];
+        var subTypeGenericArgument = subTypeGenericArguments[i];
+
+        if (baseTypeGenericArgument.IsGenericParameter ^ subTypeGenericArgument.IsGenericParameter) return false;
+        if (baseTypeGenericArgument.IsAssignableFrom(subTypeGenericArgument)) continue;
+        if (!baseTypeGenericArgument.IsGenericParameter && !subTypeGenericArgument.IsGenericParameter) return false;
+
+        if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint) &&
+            !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint)) return false;
+        if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint) &&
+            !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint)) return false;
+        if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint) &&
+            !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint)) return false;
+
+        foreach (var baseTypeGenericParameterConstraint in baseTypeGenericArgument.GetGenericParameterConstraints()) {
+          if (!subTypeGenericArgument.GetGenericParameterConstraints().Any(t => baseTypeGenericParameterConstraint.IsAssignableFrom(t))) return false;
+        }
+      }
+      return true;
+    }
+  }
+}
