protected CompositeModelInfo ResolveModelInfo(
            SetQuery <CompositeModelInfo> set,
            IEnumerable <Type> types
            )
        {
            CompositeModelInfo result = null;

            CompositeModelInfo[] modelInfos = set.Where(kvp => types.All(type => kvp.Model.PublicTypes.Any(pType => type.IsAssignableFrom(pType) || (type.IsGenericType() && pType.Equals(type.GetGenericTypeDefinition()))))).Select(kvp => kvp).ToArray();
            if (modelInfos.Length > 0)
            {
                if (modelInfos.Length == 1)
                {
                    result = modelInfos[0];
                }
                else
                {
                    result = modelInfos.FirstOrDefault(info => types.All(type => info.Model.PublicTypes.Contains(type)));
                    if (result == null)
                    {
                        throw new AmbiguousTypeException(types, modelInfos.Select(info => info.Model.PublicTypes));
                    }
                }
            }
            if (result == null)
            {
                throw new NoSuchCompositeTypeException(types);
            }
            return(result);
        }
        public CompositeModelInfo GetCompositeModelInfo(CompositeModelType modelType, IEnumerable <Type> compositeTypes)
        {
            ArgumentValidator.ValidateNotNull("Composite model type", modelType);
            ArgumentValidator.ValidateNotNull("Composite types", compositeTypes);

            CompositeModelInfo            result = null;
            SetQuery <CompositeModelInfo> dic    = null;

            if (this._compositeModels.TryGetValue(modelType, out dic))
            {
                result = this.ResolveModelInfo(dic, compositeTypes);
            }
            return(result);
        }
        protected CompositeInstanceImpl(
            CompositeInstanceStructureOwner structureOwner,
            CompositeModel model,
            IEnumerable <Type> publicCompositeTypes,
            UsesContainerQuery usesContainer,
            MainCompositeConstructorArguments publicCtorArgsObject
            )
        {
            ArgumentValidator.ValidateNotNull("Structure owner", structureOwner);
            ArgumentValidator.ValidateNotNull("Composite model", model);
            ArgumentValidator.ValidateNotEmpty("Composite type", publicCompositeTypes);
            ArgumentValidator.ValidateNotNull("Container for objects to be used in fragment creation", usesContainer);

            this._structureOwner = structureOwner;
            var application = this._structureOwner.Application;

            this._modelInfo = this._structureOwner.ModelInfoContainer.GetCompositeModelInfo(model);
            if (publicCompositeTypes.Any(pcType => pcType.ContainsGenericParameters()))
            {
                throw new InternalException("With given public composite types {" + String.Join(", ", publicCompositeTypes) + "} and public composite type in model being [" + String.Join(", ", model.PublicTypes) + "], the public composite types contained non-closed generic parameters.");
            }
            this._usesContainer = usesContainer;

            this._isPrototype = (Int32)PrototypeState.PROTOTYPE;

            this._invocationInfos = new Lazy <ThreadLocal <Stack <InvocationInfo> > >(() => new ThreadLocal <Stack <InvocationInfo> >(() => new Stack <InvocationInfo>()), LazyThreadSafetyMode.PublicationOnly);

            var composites = application.CollectionsFactory.NewDictionaryProxy <Type, Object>();
            var cProps     = application.CollectionsFactory.NewListProxy(new List <CompositeProperty>(model.Methods.Count * 2));
            var cEvents    = application.CollectionsFactory.NewListProxy(new List <CompositeEvent>(model.Methods.Count * 2));

            var publicTypeGenResult = this._modelInfo.Types;
            var factory             = publicTypeGenResult.CompositeFactory;

            var gArgs = publicTypeGenResult.PublicCompositeGenericArguments.Count == 0 ? null : new Type[publicTypeGenResult.GeneratedMainPublicType.GetGenericArguments().Length];

            this._gArgs = gArgs;

            foreach (var pType in publicCompositeTypes)
            {
                ListQuery <Int32> gArgInfo = null;
                if (publicTypeGenResult.PublicCompositeGenericArguments.TryGetValue(pType.GetGenericDefinitionIfGenericType(), out gArgInfo))
                {
                    var declaredGArgs = pType.GetGenericArguments();
                    for (Int32 i = 0; i < declaredGArgs.Length; ++i)
                    {
                        gArgs[gArgInfo[i]] = declaredGArgs[i];
                    }
                }
            }

            if (gArgs != null && gArgs.Any(gArg => gArg == null))
            {
                throw new InvalidCompositeTypeException(publicCompositeTypes, "Could not find suitable generic argument for all public types of composite " + this._modelInfo.Model + ".");
            }

            Action prePrototypeAction = null;
            var    publicCtorArgs     = new Object[publicTypeGenResult.MaxParamCountForCtors];

            Object[] compositeCtorParams = null;
            foreach (var genType in publicTypeGenResult.GeneratedPublicTypes)
            {
                var isMainType  = genType.GeneratedType.Equals(this._modelInfo.Types.GeneratedMainPublicType);
                var curCtorArgs = isMainType ? publicCtorArgs : compositeCtorParams;
                this.SetCompositeCtorArgs(ref curCtorArgs, cProps.AO, cEvents.AO);
                var publicComposite = factory.CreateInstance(genType.GeneratedTypeID, gArgs, curCtorArgs);
                foreach (var cType in this.GetTypeKeysForGeneratedType(publicComposite.GetType(), true, isMainType))
                {
                    composites[cType] = publicComposite;
                }

                if (isMainType)
                {
                    if (publicCtorArgsObject != null)
                    {
                        publicCtorArgsObject.Arguments = curCtorArgs;
                    }
                    prePrototypeAction     = (Action)publicCtorArgs[COMPOSITE_CTOR_FIRST_ADDITIONAL_PARAM_IDX];
                    this._prototypeAction  = (Action)publicCtorArgs[COMPOSITE_CTOR_FIRST_ADDITIONAL_PARAM_IDX + 1];
                    this._checkStateFunc   = (Action <IDictionary <QualifiedName, IList <ConstraintViolationInfo> > >)publicCtorArgs[COMPOSITE_CTOR_FIRST_ADDITIONAL_PARAM_IDX + 2];
                    this._compositeMethods = new Lazy <MethodInfo[]>(() => ((CompositeCallbacks)publicComposite).GetCompositeMethods(), LazyThreadSafetyMode.ExecutionAndPublication);
                }
            }

            this._isPrototypeTransitionInProgress = null;

            this.SetCompositeCtorArgs(ref compositeCtorParams, cProps.AO, cEvents.AO);

            foreach (var typeGenResult in publicTypeGenResult.PrivateCompositeGenerationResults)
            {
                var privateComposite = factory.CreateInstance(typeGenResult.GeneratedTypeID, gArgs, compositeCtorParams);
                foreach (var cTypeOrParent in this.GetTypeKeysForGeneratedType(privateComposite.GetType(), false, false))
                {
                    composites.Add(cTypeOrParent, privateComposite);
                }
            }

            this._composites = composites.CQ;

            this._methodsToModels = new Lazy <DictionaryQuery <MethodInfo, CompositeMethodModel> >(() =>
            {
                var retVal   = new Dictionary <MethodInfo, CompositeMethodModel>();
                var cMethods = this._compositeMethods.Value;
                for (var i = 0; i < cMethods.Length; ++i)
                {
                    var cm = cMethods[i];
                    retVal.Add(cm, this._modelInfo.Model.Methods[i]);
                }
                return(application.CollectionsFactory.NewDictionaryProxy(retVal).CQ);
            }, LazyThreadSafetyMode.ExecutionAndPublication);

            this._state = new CompositeStateImpl(this._structureOwner.Application.CollectionsFactory, cProps.CQ, cEvents.CQ);

            this._fragmentInstancePools = this.CreatePoolDictionary <FragmentTypeGenerationResult, FragmentInstance>(
                gArgs,
                this._modelInfo.Types.FragmentGenerationResults.Where(fGenResult => fGenResult.InstancePoolRequired),
                application.CollectionsFactory);
            var fInstances = application.CollectionsFactory.NewDictionaryProxy(new Dictionary <Type, FragmentInstance>());

            foreach (var genResult in publicTypeGenResult.FragmentGenerationResults.Where(val => !val.InstancePoolRequired))
            {
                var genType = genResult.GeneratedType;
                if (gArgs != null)
                {
                    genType = genType.MakeGenericType(gArgs);
                }
                else if (genType.ContainsGenericParameters())
                {
                    throw new InternalException("Could not find generic arguments for fragment type " + genResult.DeclaredType + ".");
                }
                fInstances.Add(genType, new FragmentInstanceImpl());
            }
            this._fragmentInstances             = fInstances.CQ;
            this._concernInvocationInstances    = this.CreatePoolDictionary <TypeGenerationResult, FragmentDependant>(gArgs, publicTypeGenResult.ConcernInvocationGenerationResults, application.CollectionsFactory);
            this._sideEffectInvocationInstances = this.CreatePoolDictionary <TypeGenerationResult, FragmentDependant>(gArgs, publicTypeGenResult.SideEffectGenerationResults, application.CollectionsFactory);
            this._constructorsForFragments      = application.CollectionsFactory.NewDictionaryProxy <Type, ListQuery <FragmentConstructorInfo> >(this._fragmentInstancePools.Keys.Concat(this._fragmentInstances.Keys)
                                                                                                                                                 .ToDictionary(
                                                                                                                                                     fType => fType,
                                                                                                                                                     fType => application.CollectionsFactory.NewListProxy(fType
                                                                                                                                                                                                          .GetAllInstanceConstructors()
                                                                                                                                                                                                          .Select(fCtor =>
            {
                Int32 idx;
                return(fCtor.TryGetConstructorModelIndex(out idx) ?
                       new FragmentConstructorInfo(model.Constructors[idx], fCtor) :
                       null);
            })
                                                                                                                                                                                                          .Where(i => i != null)
                                                                                                                                                                                                          .ToList()
                                                                                                                                                                                                          ).CQ
                                                                                                                                                     )).CQ;

            if (prePrototypeAction != null)
            {
                prePrototypeAction();
            }
        }