private static BasePredicate PredicateFromKeyValue(String key, Object value)
        {
            Operator op = Operator.FromString(key);

            if (op != null)
            {
                if (op.OpType == OperatorType.AndOr)
                {
                    var preds2 = PredicatesFromObject(value);
                    return(new AndOrPredicate(op, preds2));
                }
                else if (op.OpType == OperatorType.Unary)
                {
                    BasePredicate pred = PredicateFromObject(value);
                    return(new UnaryPredicate(op, pred));
                }
                else
                {
                    throw new Exception("Invalid operator in context: " + key);
                }
            }

            if (value == null || TypeFns.IsPredefinedType(value.GetType()))
            {
                return(new BinaryPredicate(BinaryOperator.Equals, key, value));
            }
            else if (value is IDictionary <string, object> && ((IDictionary <string, object>)value).ContainsKey("value"))
            {
                return(new BinaryPredicate(BinaryOperator.Equals, key, value));
            }

            if (!(value is Dictionary <string, object>))
            {
                throw new Exception("Unable to resolve value associated with key:" + key);
            }

            var preds = new List <BasePredicate>();
            var map   = (Dictionary <string, object>)value;


            foreach (var subKey in map.Keys)
            {
                Operator      subOp  = Operator.FromString(subKey);
                Object        subVal = map[subKey];
                BasePredicate pred;
                if (subOp != null)
                {
                    if (subOp.OpType == OperatorType.AnyAll)
                    {
                        BasePredicate subPred = PredicateFromObject(subVal);
                        pred = new AnyAllPredicate(subOp, key, subPred);
                    }
                    else if (subOp.OpType == OperatorType.Binary)
                    {
                        pred = new BinaryPredicate(subOp, key, subVal);
                    }
                    else
                    {
                        throw new Exception("Unable to resolve OperatorType for key: " + subKey);
                    }
                    // next line old check was for null not 'ContainsKey'
                }
                else if (subVal is IDictionary <string, object> && ((IDictionary <string, object>)subVal).ContainsKey("value"))
                {
                    pred = new BinaryPredicate(BinaryOperator.Equals, key, subVal);
                }
                else
                {
                    throw new Exception("Unable to resolve BasePredicate after: " + key);
                }
                preds.Add(pred);
            }
            return(CreateCompoundPredicate(preds));
        }
        private Expression BuildBinaryExpr(Expression expr1, Expression expr2, Operator op)
        {
            if (expr1.Type != expr2.Type)
            {
                if (TypeFns.IsNullableType(expr1.Type) && !TypeFns.IsNullableType(expr2.Type))
                {
                    if (!expr2.Type.IsEnum)
                    {
                        expr2 = Expression.Convert(expr2, expr1.Type);
                    }
                    else
                    {
                        expr1 = Expression.Convert(expr1, expr2.Type);
                    }
                }
                else if (TypeFns.IsNullableType(expr2.Type) && !TypeFns.IsNullableType(expr1.Type))
                {
                    if (!expr1.Type.IsEnum)
                    {
                        expr1 = Expression.Convert(expr1, expr2.Type);
                    }
                    else
                    {
                        expr2 = Expression.Convert(expr2, expr1.Type);
                    }
                }

                if (HasNullValue(expr2) && CannotBeNull(expr1))
                {
                    expr1 = Expression.Convert(expr1, TypeFns.GetNullableType(expr1.Type));
                }
                else if (HasNullValue(expr1) && CannotBeNull(expr2))
                {
                    expr2 = Expression.Convert(expr2, TypeFns.GetNullableType(expr2.Type));
                }
            }

            if (op == BinaryOperator.Equals)
            {
                return(Expression.Equal(expr1, expr2));
            }
            else if (op == BinaryOperator.NotEquals)
            {
                return(Expression.NotEqual(expr1, expr2));
            }
            else if (op == BinaryOperator.GreaterThan)
            {
                return(Expression.GreaterThan(expr1, expr2));
            }
            else if (op == BinaryOperator.GreaterThanOrEqual)
            {
                return(Expression.GreaterThanOrEqual(expr1, expr2));
            }
            else if (op == BinaryOperator.LessThan)
            {
                return(Expression.LessThan(expr1, expr2));
            }
            else if (op == BinaryOperator.LessThanOrEqual)
            {
                return(Expression.LessThanOrEqual(expr1, expr2));
            }
            else if (op == BinaryOperator.StartsWith)
            {
                var mi = TypeFns.GetMethodByExample((String s) => s.StartsWith("abc"));
                return(Expression.Call(expr1, mi, expr2));
            }
            else if (op == BinaryOperator.EndsWith)
            {
                var mi = TypeFns.GetMethodByExample((String s) => s.EndsWith("abc"));
                return(Expression.Call(expr1, mi, expr2));
            }
            else if (op == BinaryOperator.Contains)
            {
                var mi = TypeFns.GetMethodByExample((String s) => s.Contains("abc"));
                return(Expression.Call(expr1, mi, expr2));
            }
            else if (op == BinaryOperator.In)
            {
                // TODO: need to generalize this past just 'string'
                var mi = TypeFns.GetMethodByExample((List <String> list) => list.Contains("abc"), expr1.Type);
                return(Expression.Call(expr2, mi, expr1));
            }

            return(null);
        }
 public BasePredicate(Operator op)
 {
     _op = op;
 }
 public BinaryPredicate(Operator op, Object expr1Source, Object expr2Source) : base(op)
 {
     Expr1Source = expr1Source;
     Expr2Source = expr2Source;
 }