/// <summary>
        /// Builds an expression which represents an instance of <see cref="IEnumerable{T}"/> whose elements are created by the
        /// <see cref="EnumerableTarget.Targets"/> of the passed <paramref name="target"/>.
        /// </summary>
        /// <param name="target">The target for which an expression is to be built.</param>
        /// <param name="context">The current compilation context.</param>
        /// <param name="compiler">The compiler to use when building expressions for child targets.</param>
        /// <returns>An expression which can be compiled into a delegate that, when executed, will create an instance of the enumerable
        /// represented by <paramref name="target"/>
        /// </returns>
        /// <remarks>
        /// The compiler is capable of producing both lazy-loaded and eager-loaded enumerables, which can be controlled via
        /// target container options.
        ///
        /// ## Lazy vs Eager loading
        ///
        /// The option <see cref="Options.LazyEnumerables"/> is read from the <paramref name="context"/> for the
        /// <see cref="EnumerableTarget.ElementType"/> of the <paramref name="target"/>.  If it is equivalent to <c>true</c>
        /// (the <see cref="Options.LazyEnumerables.Default"/>), then a lazily-loaded enumerable is constructed which will
        /// create new instances of each object in the enumerable each time it is enumerated.
        ///
        /// If the option is instead equivalent to <c>false</c>, then all instances will be created in advance, and an already-materialised
        /// enumerable is constructed.</remarks>
        protected override Expression Build(EnumerableTarget target, IExpressionCompileContext context, IExpressionCompiler compiler)
        {
            if (context.GetOption(target.ElementType, Options.LazyEnumerables.Default))
            {
                var funcs =
                    target.Targets.Select(t => compiler.BuildResolveLambdaStrong(t, context.NewContext(target.ElementType)).Compile())
                    .ToArray();

                var lazyType = typeof(LazyEnumerable <>).MakeGenericType(target.ElementType);

                var ctor = lazyType.GetConstructor(new[] { typeof(Delegate[]) });

                var lazy = ctor.Invoke(new object[] { funcs });

                return(Expression.Call(
                           Expression.Constant(lazy),
                           "GetInstances",
                           null,
                           context.ResolveContextParameterExpression));
            }
            else
            {
                List <Expression> all = new List <Expression>();

                for (var f = 0; f < target.Targets.Length; f++)
                {
                    all.Add(compiler.Build(target.Targets[f], context.NewContext(target.ElementType)));
                }

                return(Expression.New(
                           typeof(EagerEnumerable <>).MakeGenericType(target.ElementType).GetConstructors()[0],
                           Expression.NewArrayInit(target.ElementType, all)));
            }
        }