Ejemplo n.º 1
0
 public ObjectRule(ISecurityObject iobject,
     IOperator ioperator,
     OperatorMethod method)
 {
     this.securityObject = iobject;
     this.ioperator = ioperator;
     this.method = method;
     this.ruleId = Guid.NewGuid();
 }
Ejemplo n.º 2
0
        /// <summary>
        /// 获取拥有的function
        /// </summary>
        /// <param name="operId"></param>
        /// <param name="method"></param>
        /// <returns></returns>
        public static DataTable GetOwnFunction(IOperator oper, OperatorMethod method)
        {
//            SecurityObjectType objType = SecurityObjectType.Function;

//            string sql = @"select f.functionId,f.FunctionName from accessControlList a,FunctionList f where
//                            a.operatorId=@operId and a.OperatorMethod=@operMethod and a.ObjectType=@objType and a.ObjectId=f.FunctionId";

//            SqlParameter[] Parameters = new SqlParameter[3];


//            Parameters[0] = new SqlParameter("@operId", SqlDbType.UniqueIdentifier);
//            Parameters[1] = new SqlParameter("@operMethod", SqlDbType.TinyInt);
//            Parameters[2] = new SqlParameter("@objType", SqlDbType.TinyInt);


//            Parameters[0].Value = oper.OperatorId;
//            Parameters[1].Value = (int)method;
//            Parameters[2].Value = (int)objType;

//            return SqlHelper.ExecuteDataset(SqlHelper.SqlCon_QJVRMS, CommandType.Text, sql, Parameters).Tables[0];

            FunctionService fs = new FunctionService();
            return fs.GetOwnFunction(oper.OperatorId, (int)method);
        }
Ejemplo n.º 3
0
 private static void InitializeOperatorTable()
 {
     Hashtable ot = new Hashtable(28);
     ot["op_Addition"] = new OperatorMethod("__add__", "__radd__", 2);
     ot["op_Subtraction"] = new OperatorMethod("__sub__", "__rsub__", 2);
     ot["op_Multiply"] = new OperatorMethod("__mul__", "__rmul__", 2);
     ot["op_Division"] = new OperatorMethod("__div__", "__rdiv__", 2);
     ot["op_Modulus"] = new OperatorMethod("__mod__", "__rmod__", 2);
     ot["op_ExclusiveOr"] = new OperatorMethod("__xor__", "__rxor__", 2);
     ot["op_BitwiseAnd"] = new OperatorMethod("__and__", "__rand__", 2);
     ot["op_BitwiseOr"] = new OperatorMethod("__or__", "__ror__", 2);
     ot["op_LeftShift"] = new OperatorMethod("__lshift__", "__rlshift__", 2);
     ot["op_RightShift"] = new OperatorMethod("__rshift__", "__rrshift__", 2);
     ot["op_Equality"] = new OperatorMethod("__eq__", null, 2);
     ot["op_GreaterThan"] = new OperatorMethod("__gt__", null, 2);
     ot["op_LessThan"] = new OperatorMethod("__lt__", null, 2);
     ot["op_Inequality"] = new OperatorMethod("__ne__", null, 2);
     ot["op_GreaterThanOrEqual"] = new OperatorMethod("__ge__", null, 2);
     ot["op_LessThanOrEqual"] = new OperatorMethod("__le__", null, 2);
     ot["op_UnaryNegation"] = new OperatorMethod("__neg__", null, 1);
     ot["op_OnesComplement"] = new OperatorMethod("__invert__", null, 1);
     ot["op_AdditionAssignment"] = new OperatorMethod("__iadd__", null, 2);
     ot["op_SubtractionAssignment"] = new OperatorMethod("__isub__", null, 2);
     ot["op_MultiplicationAssignment"] = new OperatorMethod("__imul__", null, 2);
     ot["op_DivisionAssignment"] = new OperatorMethod("__idiv__", null, 2);
     ot["op_ModulusAssignment"] = new OperatorMethod("__imod__", null, 2);
     ot["op_LeftShiftAssignment"] = new OperatorMethod("__ilshift__", null, 2);
     ot["op_UnsignedRightShift"] = new OperatorMethod("__irshift__", null, 2);
     ot["op_BitwiseAndAssignment"] = new OperatorMethod("__iand__", null, 2);
     ot["op_ExclusiveOrAssignment"] = new OperatorMethod("__ixor__", null, 2);
     ot["op_BitwiseOrAssignment"] = new OperatorMethod("__ior__", null, 2);
     //ot["op_Implicit"] = null;
     //ot["op_Explicit"] = null;
     //ot["op_LogicalAnd"] = null;
     //ot["op_LogicalOr"] = null;
     //ot["op_Assign"] = null;
     //ot["op_SignedRightShift"] = null;
     //ot["op_Comma"] = null;
     //ot["op_Decrement"] = null;
     //ot["op_Increment"] = null;
     //ot["op_UnaryPlus"] = null;
     operatorTable = ot;
 }
Ejemplo n.º 4
0
        public static bool ModifyRole(string roleName, string description, Guid roleId, SecurityObject[] secObj, OperatorMethod method)
        {
            //            string formatcreateSql = string.Empty;
            //            formatcreateSql = @"insert into accessControlList (ObjectId,ObjectType,OperatorId,OperatorMethod)
            //                                values ('{0}',{1},'{2}',{3})";
            //            string createSql = string.Empty;


            //            string sql = string.Empty;

            //            sql = "Begin Tran Begin try ";

            //            sql += "update Roles set RoleName='{0}',Description='{1}' where roleId='{2}'";
            //            sql = string.Format(sql, roleName, description, roleId.ToString());

            //            sql += " delete from accessControlList where OperatorId='{0}' ";
            //            sql = string.Format(sql, roleId.ToString());

            //            foreach (ISecurityObject secobj in secObj)
            //            {
            //                string secObjId = secobj.ObjectId.ToString();
            //                int oType = (int)secobj.ObjectType;
            //                int methodIndex = (int)method;
            //                createSql = string.Format(formatcreateSql, secObjId, oType.ToString(), roleId.ToString(), methodIndex.ToString());

            //                sql += createSql;
            //            }

            //            sql += " Commit End try ";
            //            sql += "Begin Catch  IF @@TRANCOUNT > 0 Rollback"
            //                    + " DECLARE @ErrMsg nvarchar(4000), @ErrSeverity int"
            //                    + " SELECT @ErrMsg = ERROR_MESSAGE(),"
            //                    + " @ErrSeverity = ERROR_SEVERITY()"
            //                    + "RAISERROR(@ErrMsg, @ErrSeverity, 1)"
            //                    + " End Catch";

            //            try
            //            {
            //                SqlHelper.ExecuteNonQuery(SqlHelper.SqlCon_QJVRMS, CommandType.Text, sql);

            //                return true;
            //            }
            //            catch (Exception e)
            //            {
            //              //  QJVRMS.Common.LogWriter.WriteExceptionLog(e, true);
            //                return false;
            //            }
            QJVRMS.Common.SerializeObjectFactory sof = new QJVRMS.Common.SerializeObjectFactory();
            string objStr = sof.SerializeToBase64(secObj);

            QJVRMS.Business.RoleWS.RoleService rs = new QJVRMS.Business.RoleWS.RoleService();
            return rs.ModifyRole(roleName, description, roleId, objStr, (int)method);


        }
Ejemplo n.º 5
0
        /// <summary>
        /// 删除用户组
        /// 
        /// I:删除用户组用户
        /// II:删除受控对象
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        //public static bool Deleteuserda(Guid userId)
        //{
        //    string sql = "Begin Tran Begin try "
        //                + " Delete from Users_inRoles where UserId=@userId"
        //                + " Delete from Users where UserId=@userId"

        //                + " Commit End Try"
        //                + " Begin Catch  IF @@TRANCOUNT > 0 Rollback "
        //                + " DECLARE @ErrMsg nvarchar(4000), @ErrSeverity int "
        //                + " SELECT @ErrMsg = ERROR_MESSAGE(),"
        //                + " @ErrSeverity = ERROR_SEVERITY() "
        //                + " RAISERROR(@ErrMsg, @ErrSeverity, 1)"
        //                + " End Catch";

        //    SqlParameter[] Parameters = new SqlParameter[1];

        //    Parameters[0] = new SqlParameter("@userId", SqlDbType.UniqueIdentifier);
        //    Parameters[0].Value = userId;

        //    try
        //    {
        //        SqlHelper.ExecuteNonQuery(SqlHelper.SqlCon_QJVRMS, CommandType.Text, sql, Parameters);
        //        return true;
        //    }
        //    catch (Exception ex)
        //    {
        //        // QJVRMS.Common.LogWriter.WriteExceptionLog(ex, true);
        //        return false;
        //    }
        //}


        public static IRole NewRole(Guid groupId, string roleName, string description, SecurityObject[] secObj, OperatorMethod method)
        {
            //SqlParameter[] Parameters = new SqlParameter[4];

            //Parameters[0] = new SqlParameter("@RoleName", SqlDbType.NVarChar);
            //Parameters[1] = new SqlParameter("@description", SqlDbType.NVarChar);
            //Parameters[2] = new SqlParameter("@groupId", SqlDbType.UniqueIdentifier);
            //Parameters[3] = new SqlParameter("@roleId", SqlDbType.UniqueIdentifier);

            //Parameters[3].Direction = ParameterDirection.Output;


            //Parameters[0].Value = roleName;
            //Parameters[1].Value = description;
            //Parameters[2].Value = groupId;


            //SqlTransaction trans = null;
            Role role = null;

            //            using (SqlConnection con = new SqlConnection(SqlHelper.Con_QJVRMS))
            //            {
            //                con.Open();
            //                trans = con.BeginTransaction();

            //                try
            //                {
            //                    SqlHelper.ExecuteNonQuery(trans, CommandType.StoredProcedure, "dbo.Role_CreateRole", Parameters);
            //                    Guid roleId = new Guid(Parameters[3].Value.ToString());


            //                    string formatcreateSql = @"insert into accessControlList (ObjectId,ObjectType,OperatorId,OperatorMethod)
            //                                values ('{0}',{1},'{2}',{3})";

            //                    string sql = string.Empty;

            //                    foreach (ISecurityObject secobj in secObj)
            //                    {
            //                        string secObjId = secobj.ObjectId.ToString();
            //                        int oType = (int)secobj.ObjectType;
            //                        int methodIndex = (int)method;
            //                        sql += string.Format(formatcreateSql, secObjId, oType.ToString(), roleId.ToString(), methodIndex.ToString());


            //                    }
            //                    if( sql != string.Empty )
            //                        SqlHelper.ExecuteNonQuery(trans, CommandType.Text, sql);

            //                    role = new Role(roleId, groupId, roleName, description);


            //                    trans.Commit();
            //                }
            //                catch (Exception e)
            //                {
            //                    trans.Rollback();
            //                   // QJVRMS.Common.LogWriter.WriteExceptionLog(e, true);
            //                    throw e;
            //                }


            //            }
            QJVRMS.Common.SerializeObjectFactory sof = new QJVRMS.Common.SerializeObjectFactory();
            string objStr = sof.SerializeToBase64(secObj);

            QJVRMS.Business.RoleWS.RoleService rs = new QJVRMS.Business.RoleWS.RoleService();
            Guid roleId = rs.NewRole(groupId, roleName, description, objStr, (int)method);
            role = new Role(roleId, groupId, roleName, description);

            return role;

        }
Ejemplo n.º 6
0
        /// <summary>
        /// 绑定用户组定义功能
        /// </summary>
        void BindRoleControlList()
        {
            Dictionary <int, string> methodDict = WebUI.UIBiz.CommonInfo.GetMethodDict();
            //注意修改 当为superadmin时
            RoleCollection roles = Role.GetRoleCollection(CurrentGroupId);


            Hashtable roleRules = new Hashtable();

            foreach (Role role in roles)
            {
                ISecurityObject   securityObj = new SecurityObject(new Guid(this.hiCurrentCataId.Value), SecurityObjectType.Items);
                List <ObjectRule> rules       = new List <ObjectRule>();

                foreach (KeyValuePair <int, string> methodEntry in methodDict)
                {
                    OperatorMethod method = (OperatorMethod)((int)methodEntry.Key);
                    ObjectRule     rule   = new ObjectRule(securityObj, role, method);

                    rules.Add(rule);
                }

                roleRules.Add(role, rules);

                ObjectRule.CheckRules(rules);
            }

            DataTable roleMethod = new DataTable();

            DataColumn dc = new DataColumn("roleName");

            roleMethod.Columns.Add(dc);

            dc = new DataColumn("roleId");
            roleMethod.Columns.Add(dc);

            foreach (KeyValuePair <int, string> methodEntry in methodDict)
            {
                string mIndex = methodEntry.Key.ToString();
                roleMethod.Columns.Add(mIndex, typeof(bool));
            }


            //foreach (KeyValuePair<int, string> methodEntry in methodDict)
            //{
            //   TemplateField field = new TemplateField();
            //  //  CheckBoxField field = new CheckBoxField();
            //    WebUI.UIBiz.GridViewTempla template = new WebUI.UIBiz.GridViewTempla(ListItemType.Item, string.Empty);

            //    field.HeaderText = methodEntry.Value.ToString();
            //   // field.DataField = methodEntry.Key.ToString();
            //   // field.ReadOnly = false;

            //   field.ItemTemplate = template;
            //    roleGroupList.Columns.Add(field);

            //    DataColumn methodDc = new DataColumn(methodEntry.Key.ToString());
            //    roleMethod.Columns.Add(methodDc);
            //}



            foreach (DictionaryEntry entry in roleRules)
            {
                Role role = entry.Key as Role;
                List <ObjectRule> rules = entry.Value as List <ObjectRule>;

                DataRow dr = roleMethod.NewRow();
                dr["roleName"] = role.RoleName;
                dr["roleId"]   = role.RoleId.ToString();

                foreach (IRule rule in rules)
                {
                    string methodKey = ((int)rule.Method).ToString();
                    dr[methodKey] = rule.IsValidate;
                }

                roleMethod.Rows.Add(dr);
            }

            DataView dv = roleMethod.DefaultView;

            dv.Sort = "RoleName";
            roleGroupList.DataSource = dv;
            roleGroupList.DataBind();



            //   TemplateColumn roleColumn = new TemplateColumn();
        }
Ejemplo n.º 7
0
        static BinaryArithmicExpression()
        {
            #region Init

            _operatorMethods["+"] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(float), BEH.CalcFloat),
                new OperatorMethod(typeof(double), BEH.CalcDouble),
                new OperatorMethod(typeof(decimal), BEH.CalcDecimal),
                new OperatorMethod(typeof(string), BEH.CalcString),
                new OperatorMethod(typeof(string), typeof(string), typeof(object), BEH.CalcStringObject),
                new OperatorMethod(typeof(string), typeof(object), typeof(string), BEH.CalcObjectString)
            };

            _operatorMethods["-"] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(float), BEH.CalcFloat),
                new OperatorMethod(typeof(double), BEH.CalcDouble),
                new OperatorMethod(typeof(decimal), BEH.CalcDecimal)
            };
            _operatorMethods["*"] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(float), BEH.CalcFloat),
                new OperatorMethod(typeof(double), BEH.CalcDouble),
                new OperatorMethod(typeof(decimal), BEH.CalcDecimal)
            };
            _operatorMethods["/"] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(float), BEH.CalcFloat),
                new OperatorMethod(typeof(double), BEH.CalcDouble),
                new OperatorMethod(typeof(decimal), BEH.CalcDecimal)
            };
            _operatorMethods["%"] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(float), BEH.CalcFloat),
                new OperatorMethod(typeof(double), BEH.CalcDouble),
                new OperatorMethod(typeof(decimal), BEH.CalcDecimal)
            };
            _operatorMethods["<<"] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(uint), typeof(uint), typeof(int), BEH.CalcUInt32_Int32),
                new OperatorMethod(typeof(long), typeof(long), typeof(int), BEH.CalcInt64_Int32),
                new OperatorMethod(typeof(ulong), typeof(ulong), typeof(int), BEH.CalcUInt64_Int32)
            };
            _operatorMethods[">>"] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(uint), typeof(uint), typeof(int), BEH.CalcUInt32_Int32),
                new OperatorMethod(typeof(long), typeof(long), typeof(int), BEH.CalcInt64_Int32),
                new OperatorMethod(typeof(ulong), typeof(ulong), typeof(int), BEH.CalcUInt64_Int32)
            };
            _operatorMethods["=="] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(bool), typeof(int), typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(bool), typeof(uint), typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(bool), typeof(long), typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(bool), typeof(ulong), typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(bool), typeof(float), typeof(float), BEH.CalcFloat),
                new OperatorMethod(typeof(bool), typeof(double), typeof(double), BEH.CalcDouble),
                new OperatorMethod(typeof(bool), typeof(decimal), typeof(decimal), BEH.CalcDecimal),
                new OperatorMethod(typeof(bool), typeof(string), typeof(string), BEH.CalcString),
                new OperatorMethod(typeof(bool), BEH.CalcBool)
            };
            _operatorMethods["!="] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(bool), typeof(int), typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(bool), typeof(uint), typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(bool), typeof(long), typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(bool), typeof(ulong), typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(bool), typeof(float), typeof(float), BEH.CalcFloat),
                new OperatorMethod(typeof(bool), typeof(double), typeof(double), BEH.CalcDouble),
                new OperatorMethod(typeof(bool), typeof(decimal), typeof(decimal), BEH.CalcDecimal),
                new OperatorMethod(typeof(bool), typeof(string), typeof(string), BEH.CalcString),
                new OperatorMethod(typeof(bool), BEH.CalcBool)
            };
            _operatorMethods["<"] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(bool), typeof(int), typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(bool), typeof(uint), typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(bool), typeof(long), typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(bool), typeof(ulong), typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(bool), typeof(float), typeof(float), BEH.CalcFloat),
                new OperatorMethod(typeof(bool), typeof(double), typeof(double), BEH.CalcDouble),
                new OperatorMethod(typeof(bool), typeof(decimal), typeof(decimal), BEH.CalcDecimal),
            };
            _operatorMethods[">"] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(bool), typeof(int), typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(bool), typeof(uint), typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(bool), typeof(long), typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(bool), typeof(ulong), typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(bool), typeof(float), typeof(float), BEH.CalcFloat),
                new OperatorMethod(typeof(bool), typeof(double), typeof(double), BEH.CalcDouble),
                new OperatorMethod(typeof(bool), typeof(decimal), typeof(decimal), BEH.CalcDecimal),
            };
            _operatorMethods["<="] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(bool), typeof(int), typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(bool), typeof(uint), typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(bool), typeof(long), typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(bool), typeof(ulong), typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(bool), typeof(float), typeof(float), BEH.CalcFloat),
                new OperatorMethod(typeof(bool), typeof(double), typeof(double), BEH.CalcDouble),
                new OperatorMethod(typeof(bool), typeof(decimal), typeof(decimal), BEH.CalcDecimal),
            };
            _operatorMethods[">="] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(bool), typeof(int), typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(bool), typeof(uint), typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(bool), typeof(long), typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(bool), typeof(ulong), typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(bool), typeof(float), typeof(float), BEH.CalcFloat),
                new OperatorMethod(typeof(bool), typeof(double), typeof(double), BEH.CalcDouble),
                new OperatorMethod(typeof(bool), typeof(decimal), typeof(decimal), BEH.CalcDecimal),
            };
            _operatorMethods["&"] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(bool), BEH.CalcBool)
            };
            _operatorMethods["|"] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(bool), BEH.CalcBool)
            };
            _operatorMethods["^"] = new OperatorMethod[]
            {
                new OperatorMethod(typeof(int), BEH.CalcInt32),
                new OperatorMethod(typeof(uint), BEH.CalcUInt32),
                new OperatorMethod(typeof(long), BEH.CalcInt64),
                new OperatorMethod(typeof(ulong), BEH.CalcUInt64),
                new OperatorMethod(typeof(bool), BEH.CalcBool)
            };

            #endregion
        }
Ejemplo n.º 8
0
        public override ValueExpression Evaluate(ITemplateContext context)
        {
            ValueExpression[] values = new ValueExpression[] { Left.Evaluate(context), Right.Evaluate(context) };
            Type type1 = values[0].Type;
            Type type2 = values[1].Type;

            bool nullable1 = type1.IsGenericType && type1.GetGenericTypeDefinition() == typeof(Nullable <>);
            bool nullable2 = type2.IsGenericType && type2.GetGenericTypeDefinition() == typeof(Nullable <>);

            type1 = Nullable.GetUnderlyingType(type1) ?? type1;
            type2 = Nullable.GetUnderlyingType(type2) ?? type2;

            bool           isNullable     = (nullable1 || nullable2);
            OperatorMethod operatorMethod = FindOperatorMethod(type1, type2);

            if (operatorMethod == null)
            {
                Type promotionType = null;

                if (type1 == typeof(decimal) || type2 == typeof(decimal))
                {
                    promotionType = typeof(decimal);
                }
                else if (type1 == typeof(double) || type2 == typeof(double))
                {
                    promotionType = typeof(double);
                }
                else if (type1 == typeof(float) || type2 == typeof(float))
                {
                    promotionType = typeof(float);
                }
                else if (type1 == typeof(ulong) || type2 == typeof(ulong))
                {
                    promotionType = typeof(ulong);
                }
                else if (type1 == typeof(long) || type2 == typeof(long))
                {
                    promotionType = typeof(long);
                }
                else if (type1 == typeof(uint) || type2 == typeof(uint) && (type1 == typeof(sbyte) || type2 == typeof(sbyte) || type1 == typeof(short) || type2 == typeof(short) || type1 == typeof(int) || type2 == typeof(int)))
                {
                    promotionType = typeof(long);
                }
                else if (type1 == typeof(uint) || type2 == typeof(uint))
                {
                    promotionType = typeof(uint);
                }
                else if (type1.IsPrimitive && type2.IsPrimitive && type1 != typeof(bool) && type2 != typeof(bool))
                {
                    promotionType = typeof(int);
                }

                if (promotionType != null)
                {
                    type1 = promotionType;
                    type2 = promotionType;
                }

                operatorMethod = FindOperatorMethod(type1, type2);
            }

            if (operatorMethod == null)
            {
                if (_operator == "==" || _operator == "!=")
                {
                    return(new ValueExpression(BEH.CalcObject(_operator, values[0].Value, values[1].Value), typeof(bool)));
                }

                throw new ArithmeticException();
            }

            Type returnType = operatorMethod.ReturnType;

            if (isNullable)
            {
                returnType = typeof(Nullable <>).MakeGenericType(returnType);

                //TODO: check specs for bool? values
                if (values[0].Value == null || values[1].Value == null)
                {
                    return(new ValueExpression(null, returnType));
                }
            }

            object value1 = Convert.ChangeType(values[0].Value, operatorMethod.Type1);
            object value2 = Convert.ChangeType(values[1].Value, operatorMethod.Type2);

            return(new ValueExpression(operatorMethod.Function(_operator, value1, value2), returnType));
        }