public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture)
        {
            object            obj2;
            ArithmeticLiteral literal;
            ArithmeticLiteral literal2;
            Literal           literal3;
            Literal           literal4;

            if (this.lhsRootType == null)
            {
                this.lhsRootType = Enum.GetUnderlyingType(this.lhsBaseType);
            }
            if (this.rhsRootType == null)
            {
                this.rhsRootType = Enum.GetUnderlyingType(this.rhsBaseType);
            }
            switch (this.op)
            {
            case CodeBinaryOperatorType.Add:
                if ((parameters[0] != null) && (parameters[1] != null))
                {
                    literal  = ArithmeticLiteral.MakeLiteral(this.lhsRootType, parameters[0]);
                    literal2 = ArithmeticLiteral.MakeLiteral(this.rhsRootType, parameters[1]);
                    obj2     = literal.Add(literal2);
                    obj2     = Executor.AdjustType(obj2.GetType(), obj2, this.resultBaseType);
                    if (this.resultIsNullable)
                    {
                        obj2 = Activator.CreateInstance(this.resultType, new object[] { obj2 });
                    }
                    return(obj2);
                }
                return(null);

            case CodeBinaryOperatorType.Subtract:
                if ((parameters[0] != null) && (parameters[1] != null))
                {
                    literal  = ArithmeticLiteral.MakeLiteral(this.resultRootType, Executor.AdjustType(this.lhsRootType, parameters[0], this.resultRootType));
                    literal2 = ArithmeticLiteral.MakeLiteral(this.resultRootType, Executor.AdjustType(this.rhsRootType, parameters[1], this.resultRootType));
                    obj2     = literal.Subtract(literal2);
                    obj2     = Executor.AdjustType(obj2.GetType(), obj2, this.resultBaseType);
                    if (this.resultIsNullable)
                    {
                        obj2 = Activator.CreateInstance(this.resultType, new object[] { obj2 });
                    }
                    return(obj2);
                }
                return(null);

            case CodeBinaryOperatorType.ValueEquality:
                literal3 = Literal.MakeLiteral(this.lhsRootType, parameters[0]);
                literal4 = Literal.MakeLiteral(this.rhsRootType, parameters[1]);
                return(literal3.Equal(literal4));

            case CodeBinaryOperatorType.LessThan:
                literal3 = Literal.MakeLiteral(this.lhsRootType, parameters[0]);
                literal4 = Literal.MakeLiteral(this.rhsRootType, parameters[1]);
                return(literal3.LessThan(literal4));

            case CodeBinaryOperatorType.LessThanOrEqual:
                literal3 = Literal.MakeLiteral(this.lhsRootType, parameters[0]);
                literal4 = Literal.MakeLiteral(this.rhsRootType, parameters[1]);
                return(literal3.LessThanOrEqual(literal4));

            case CodeBinaryOperatorType.GreaterThan:
                literal3 = Literal.MakeLiteral(this.lhsRootType, parameters[0]);
                literal4 = Literal.MakeLiteral(this.rhsRootType, parameters[1]);
                return(literal3.GreaterThan(literal4));

            case CodeBinaryOperatorType.GreaterThanOrEqual:
                literal3 = Literal.MakeLiteral(this.lhsRootType, parameters[0]);
                literal4 = Literal.MakeLiteral(this.rhsRootType, parameters[1]);
                return(literal3.GreaterThanOrEqual(literal4));
            }
            throw new RuleEvaluationException(string.Format(CultureInfo.CurrentCulture, Messages.BinaryOpNotSupported, new object[] { this.op.ToString() }));
        }