private static FilterSpecification <T> CombineSpecification(FilterSpecification <T> left, FilterSpecification <T> right, Func <Expression, Expression, BinaryExpression> combiner)
        {
            var expr1    = left.SpecificationExpression;
            var expr2    = right.SpecificationExpression;
            var arg      = Expression.Parameter(typeof(T));
            var combined = combiner.Invoke(
                new ReplaceParameterVisitor {
                { expr1.Parameters.Single(), arg }
            }.Visit(expr1.Body),
                new ReplaceParameterVisitor {
                { expr2.Parameters.Single(), arg }
            }.Visit(expr2.Body));

            return(new ConstructedSpecification <T>(Expression.Lambda <Func <T, bool> >(combined, arg)));
        }
 public FilterSpecification <T> Or(FilterSpecification <T> other)
 {
     return(this | other);
 }
 public FilterSpecification <T> And(FilterSpecification <T> other)
 {
     return(this & other);
 }
        public static FilterSpecification <TDerived> ConvertSpecification <TBase, TDerived>(FilterSpecification <TBase> original) where TDerived : TBase
        {
            var expr1 = original.SpecificationExpression;
            var arg = Expression.Parameter(typeof(TDerived));
            var newBody = new ReplaceParameterVisitor {
                { expr1.Parameters.Single(), arg }
            }.Visit(expr1.Body);

            return(new ConvertedSpecification <TDerived>(Expression.Lambda <Func <TDerived, bool> >(newBody, arg)));
        }