/// <summary>
        /// Build the entire type tree and type cache
        /// </summary>
        private void BuildTypeTree()
        {
            // Start with all public types
            var allTypes        = new List <Type>();
            var registeredTypes = Container.GetRegisteredImplementations(typeof(IResource)).ToList();

            // Load full type tree from registered resources
            foreach (var type in registeredTypes.Union(ReflectionTool.GetPublicClasses <Resource>()))
            {
                var buffer = type;
                // Exclude the different base types from "Moryx.Resources" from the type tree
                do
                {
                    if (buffer.IsGenericType) // Generic base types appear multiple times, use only the generic type
                    {
                        buffer = buffer.GetGenericTypeDefinition();
                    }
                    if (!allTypes.Contains(buffer))
                    {
                        allTypes.Add(buffer);
                    }
                    buffer = buffer.BaseType;
                } while (buffer != null && buffer != typeof(Resource));
            }

            // Convert tree to TypeNodes objects
            RootType = Convert(typeof(Resource), allTypes, registeredTypes);
        }
        /// <summary>
        /// Get all interfaces of a linker that are relevant for the public proxy. This excludes all non-public
        /// interfaces or interfaces that are not derived from IPublicResource.
        /// </summary>
        private static IReadOnlyList <Type> RelevantInterfaces(ResourceTypeNode node)
        {
            var interfaces         = node.ResourceType.GetInterfaces();
            var relevantInterfaces = new List <Type>(interfaces.Length); // At max all interfaces are relevant

            // Load additional public interfaces from resource registration attribute
            var additionalPublicInterfaces = node.ResourceType.GetCustomAttributes <ResourceAvailableAsAttribute>()
                                             .SelectMany(a => a.AvailableAs).Distinct();

            // Add all resources derived from IResource, but not IResource itself
            relevantInterfaces.AddRange(from resourceInterface in interfaces
                                        where resourceInterface.IsPublic &&
                                        ((typeof(IResource).IsAssignableFrom(resourceInterface) &&
                                          !resourceInterface.IsAssignableFrom(typeof(IResource))) ||
                                         additionalPublicInterfaces.Contains(resourceInterface))
                                        select resourceInterface);

            // Add all interfaces that are NOT derived from IResource BUT part of any of the relevant interfaces
            relevantInterfaces.AddRange(from generalInterface in interfaces
                                        where !generalInterface.IsAssignableFrom(typeof(IResource)) && // It should not be a base type if IResource
                                        !relevantInterfaces.Contains(generalInterface) &&    // It should not be part of the relevant interfaces yet
                                        relevantInterfaces.Any(generalInterface.IsAssignableFrom)       // It is a base type of a relevant interface
                                        select generalInterface);

            return(relevantInterfaces);
        }
        private ResourceTypeNode Convert(Type type, ICollection <Type> allTypes, ICollection <Type> registeredTypes, ResourceTypeNode baseType = null)
        {
            // Create linker from type
            var linker = new ResourceTypeNode
            {
                ResourceType = type,
                BaseType     = baseType,
                IsRegistered = registeredTypes.Contains(type),
                Constructors = (from method in type.GetMethods()
                                let att = method.GetCustomAttribute <ResourceConstructorAttribute>()
                                          where att != null
                                          orderby att.IsDefault descending
                                          select method).ToArray()
            };

            // Find all derived types
            // ReSharper disable once PossibleNullReferenceException -> There is always a base type
            var derived = allTypes.Where(t => (t.BaseType.IsGenericType ? t.BaseType.GetGenericTypeDefinition() : t.BaseType) == type);

            linker.DerivedTypes = derived.Select(t => Convert(t, allTypes, registeredTypes, linker)).ToArray();

            // Save reference in type cache
            _typeCache[linker.Name] = linker;

            return(linker);
        }
        /// <summary>
        /// Recursively check if any type in the tree supports the referenced type
        /// </summary>
        /// <param name="type">Current node in the recursive call</param>
        /// <param name="typeConstraints">All type constraints a candidate needs to match to be compatible</param>
        /// <param name="supportedTypes">Current list of supported types</param>
        private static void SupportingType(ResourceTypeNode type, ICollection <Type> typeConstraints, ICollection <ResourceTypeNode> supportedTypes)
        {
            // This type supports the property -> Convert it and break recursion
            if (typeConstraints.All(tc => tc.IsAssignableFrom(type.ResourceType)))
            {
                supportedTypes.Add(type);
                return;
            }

            // Otherwise check its derived types
            foreach (var derivedType in type.DerivedTypes)
            {
                SupportingType(derivedType, typeConstraints, supportedTypes);
            }
        }