public static Expression Clean(Expression expression, bool filter, HeavyProfiler.Tracer log)
        {
            Expression clean = ExpressionCleaner.Clean(expression);

            log.Switch("OvrLdSmp");
            Expression simplified = OverloadingSimplifier.Simplify(clean);

            log.Switch("QrFlr");
            Expression filtered = QueryFilterer.Filter(simplified, filter);

            return(filtered);
        }
        internal static Expression Optimize(Expression binded, QueryBinder binder, AliasGenerator aliasGenerator, HeavyProfiler.Tracer log)
        {
            log.Switch("Aggregate");
            Expression rewrited = AggregateRewriter.Rewrite(binded);

            log.Switch("EntityCompleter");
            Expression completed = EntityCompleter.Complete(rewrited, binder);

            log.Switch("AliasReplacer");
            Expression replaced = AliasProjectionReplacer.Replace(completed, aliasGenerator);

            log.Switch("OrderBy");
            Expression orderRewrited = OrderByRewriter.Rewrite(replaced);

            log.Switch("Rebinder");
            Expression rebinded = QueryRebinder.Rebind(orderRewrited);

            log.Switch("UnusedColumn");
            Expression columnCleaned = UnusedColumnRemover.Remove(rebinded);

            log.Switch("Redundant");
            Expression subqueryCleaned = RedundantSubqueryRemover.Remove(columnCleaned);

            log.Switch("Condition");
            Expression rewriteConditions = ConditionsRewriter.Rewrite(subqueryCleaned);

            log.Switch("Scalar");
            Expression scalar = ScalarSubqueryRewriter.Rewrite(rewriteConditions);

            return(scalar);
        }