/// <inheritdoc/>
        protected override Expression VisitLambda(LambdaExpression l)
        {
            Expression body = Visit(l.Body);

            if (body != l.Body)
            {
                return(FastExpression.Lambda(l.Type, body, l.Parameters));
            }
            return(l);
        }
        /// <summary>
        /// Extracts constants from <see cref="LambdaExpression"/> specified in constructor.
        /// Result is a <see cref="LambdaExpression"/> with one additional parameter (array of objects).
        /// Extra parameter is added to first position.
        /// </summary>
        /// <returns><see cref="LambdaExpression"/> with all constants extracted to additional parameter.</returns>
        public LambdaExpression Process()
        {
            if (constantValues != null)
            {
                throw new InvalidOperationException();
            }
            constantValues = new List <object>();
            var parameters = EnumerableUtils.One(constantParameter).Concat(lambda.Parameters).ToArray();
            var body       = Visit(lambda.Body);

            // Preserve original delegate type because it may differ from types of parameters / return value
            return(FastExpression.Lambda(FixDelegateType(lambda.Type), body, parameters));
        }