private Expression BuildDecoratorExpression(IDecoratableEnumerable collection,
                                                    out IEnumerable <KnownRelationship> foundRelationships)
        {
            foundRelationships = Enumerable.Empty <KnownRelationship>();

            // When we're dealing with a Singleton decorator, we must cache the list, because other theads
            // could create another 'singleton' instance of this decorator. But since this list is at this
            // point currently just a list of Expressions (returned as constant), we can always cache this
            // list, even if the decorator is transient. This cache is an instance list, since it is specific
            // to the current decorator registration.
            lock (this.decoratableEnumerablesCache)
            {
                IDecoratableEnumerable decoratedCollection;

                if (!this.decoratableEnumerablesCache.TryGetValue(this.registeredServiceType,
                                                                  out decoratedCollection))
                {
                    decoratedCollection =
                        this.BuildDecoratableEnumerable(collection, out foundRelationships);

                    this.decoratableEnumerablesCache[this.registeredServiceType] = decoratedCollection;
                }

                return(Expression.Constant(decoratedCollection));
            }
        }
        private IDecoratableEnumerable BuildDecoratableEnumerable(IDecoratableEnumerable originalDecoratables,
                                                                  out IEnumerable <KnownRelationship> foundRelationships)
        {
            var contexts = (
                from context in originalDecoratables.GetDecoratorPredicateContexts()
                let predicateIsSatisfied = this.SatisfiesPredicate(context)
                                           select new
            {
                IsDecorated = predicateIsSatisfied,
                OriginalContext = context,
                Context = predicateIsSatisfied ? this.DecorateContext(context) : context,
            })
                           .ToArray();

            foundRelationships = (
                from context in contexts
                where context.IsDecorated
                let dependency = context.OriginalContext.Registration
                                 let decoratorRegistration = context.Context.Registration.Registration
                                                             from relationship in this.GetKnownDecoratorRelationships(decoratorRegistration,
                                                                                                                      this.decoratorConstructor, this.registeredServiceType, dependency)
                                                             select relationship)
                                 .ToArray();

            var allContexts = contexts.Select(c => c.Context).ToArray();

            return(DecoratorHelpers.CreateDecoratedEnumerable(this.registeredServiceType, this.Container,
                                                              allContexts));
        }