private Expression MakeSelect(CurrentDependencies current, LambdaExpression selector)
        {
            var subExtractor = new DependenciesExtractor(selector, parameters.Concat(selector.Parameters));

            LambdaExpression[] primarySubDependencies;
            LambdaExpression[] additionalSubDependencies;
            subExtractor.Extract(out primarySubDependencies, out additionalSubDependencies);
            var prefixCurrent = MakeLambda(GotoCurrent(current.Prefix));

            current.AddSubDependencies(prefixCurrent, additionalSubDependencies);

            if (primarySubDependencies.Length > 1)
            {
                return(Expression.NewArrayInit(typeof(object), primarySubDependencies.Select(exp => Expression.Convert(prefixCurrent.Merge(exp).Body, typeof(object)))));
            }

            var primarySubDependency = primarySubDependencies.SingleOrDefault();

            if (primarySubDependency == null)
            {
                return(Expression.NewArrayInit(typeof(object)));
            }
            if (!selector.ReturnType.IsAssignableFrom(primarySubDependency.ReturnType))
            {
                return(null);
            }

            if (!(primarySubDependency.Body is NewExpression))
            {
                return(new AnonymousTypeEliminator().Eliminate(prefixCurrent.Merge(primarySubDependency)).Body);
            }
            var newExpression = (NewExpression)primarySubDependency.Body;

            return(Expression.New(newExpression.Constructor, newExpression.Arguments.Select(arg => prefixCurrent.Merge(Expression.Lambda(arg, primarySubDependency.Parameters)).Body)));
        }
        private void ProcessLinqSelectMany(MethodInfo method, CurrentDependencies current, Expression[] arguments)
        {
            var collectionSelector = (LambdaExpression)arguments[0];
            var collection         = MakeSelect(current, collectionSelector);

            if (collection == null)
            {
                current.Prefix = null;
                return;
            }

            if (arguments.Length == 1)
            {
                current.Prefix = collection;
                return;
            }

            var resultSelector = (LambdaExpression)arguments[1];
            var subExtractor   = new DependenciesExtractor(resultSelector, parameters.Concat(resultSelector.Parameters));

            LambdaExpression[] primarySubDependencies;
            LambdaExpression[] additionalSubDependencies;
            subExtractor.Extract(out primarySubDependencies, out additionalSubDependencies);
            var prefixCurrent     = MakeLambda(GotoCurrent(current.Prefix));
            var collectionCurrent = MakeLambda(GotoCurrent(collection));

            current.AddSubDependencies(prefixCurrent, collectionCurrent, additionalSubDependencies);
            var primarySubDependency = primarySubDependencies.Single();

            if (!(primarySubDependency.Body is NewExpression))
            {
                current.Prefix = new AnonymousTypeEliminator().Eliminate(new ExpressionMerger(prefixCurrent, collectionCurrent).Merge(primarySubDependency)).Body;
            }
            else
            {
                var newExpression = (NewExpression)primarySubDependency.Body;
                current.Prefix = Expression.New(newExpression.Constructor, newExpression.Arguments.Select(arg => new ExpressionMerger(prefixCurrent, collectionCurrent).Merge(Expression.Lambda(arg, primarySubDependency.Parameters)).Body));
            }
        }