private static ICollection <MethodInfo> GetConcreteMethods(MethodInfo method, LinkList <Binding> bindings)
        {
            Debug.Assert(method != null);
            Debug.Assert(bindings != null);


            // Try to resolve generic arguments on method.
            var openArguments    = GenericTypeResolver.GetOpenGenericArguments(method.GetGenericArguments( ));
            var concreteBindings = new BindingCollection(bindings);

            GenericTypeResolver.BindGenericArguments(concreteBindings, openArguments);

            var concreteMethods = concreteBindings.Transform((b) => MakeConcreteMethod(method, openArguments, b));


            // If generic arguments cannot be resolved statically, try to bind method arguments by searching for creatable parameter types.
            if (concreteMethods.Count == 0)
            {
                var genericParameterTypes = method.GetParameters( )
                                            .Select(p => p.ParameterType)
                                            .Where(t => t.IsGenericType)
                                            .ToArray( );
                Debug.Assert(genericParameterTypes.All(t => !t.IsGenericParameter));

                var creatableParameterTypes = genericParameterTypes
                                              .Select(t => TypeCreator.GetCreators(t)
                                                      .Select(c => c.InstanceType)
                                                      .Distinct( )
                                                      );

                var parameterBindings = new BindingCollection(bindings);
                parameterBindings.Expand(Permuter.Permute(creatableParameterTypes), (b, permutation) => {
                    for (int i = 0; i < permutation.Length; ++i)
                    {
                        Type permutationType      = permutation[i];
                        Type genericParameterType = genericParameterTypes[i];
                        GenericTypeResolver.GetAssignedGenericArguments(b, permutationType, genericParameterType);
                    }
                });

                concreteMethods = parameterBindings.Transform((b) => MakeConcreteMethod(method, openArguments, b));
            }


            return(concreteMethods);
        }
        private static BindingCollection GetConcreteTypeBindings(Type type, LinkList <Binding> bindings, out LinkList <Type> openArguments)
        {
            Debug.Assert(type != null);
            Debug.Assert(bindings != null);


            // Avoid recursive searches for generic type.
            if (type.ContainsGenericParameters)
            {
                if (Binding.ContainsType(bindings, type))
                {
                    openArguments = LinkList <Type> .Empty;
                    return(new BindingCollection( ));
                }
                bindings = bindings.Add(new Binding(null, type));
            }

            // Bind all unassigned generic argument on the generic type.
            openArguments = GenericTypeResolver.GetOpenGenericArguments(type);
            var collection = new BindingCollection(bindings);

            GenericTypeResolver.BindGenericArguments(collection, openArguments);
            return(collection);
        }