/// <summary>
        /// Параметры функции
        /// PARAM_DEVICE_ID - идентификатор устройства        
        /// PARAM_DEVICE_TYPE - тип устройства
        /// PARAM_DEVICE_MAC - MAC адрес устройства        
        /// PARAM_DEVICE_NAME - имя устройства
        /// PARAM_LOGIN - логин пользователя
        /// PARAM_PASSWORD - пароль пользователя
        /// PARAM_SESSION_DEADLINE - дата окончания сессии
        /// PARAM_LOCALE - локаль клиентского устройства
        /// </summary>
        /// <param name="Parameters">Параметры</param>
        /// <returns></returns>
        public override CFunctionResult Execute(Dictionary<string, object> Parameters)
        {
            CFunctionResult Result = new CFunctionResult();
            CultureInfo ClientCulture = (Parameters.ContainsKey(CServerFunctionParams.CONST_FUNC_PARAM_LOCALE) ? CultureInfo.GetCultureInfo((int)Parameters[CServerFunctionParams.CONST_FUNC_PARAM_LOCALE]) : CultureInfo.CurrentCulture);

            if (!Parameters.ContainsKey(CServerFunctionParams.CONST_FUNC_PARAM_LOGIN))
                return this._compileResult(EnFunctionResultType.EError, Parameters, CGlobalizationHelper.sGetStringResource("ERROR_MSG_LOGIN_NULL", ClientCulture));
            if (!Parameters.ContainsKey(CServerFunctionParams.CONST_FUNC_PARAM_PASSWORD))
                return this._compileResult(EnFunctionResultType.EError, Parameters, CGlobalizationHelper.sGetStringResource("ERROR_MSG_PASSWORD_NULL", ClientCulture));
            if (!Parameters.ContainsKey(CServerFunctionParams.CONST_FUNC_PARAM_SESSION_DEADLINE))
                return this._compileResult(EnFunctionResultType.EError, Parameters, CGlobalizationHelper.sGetStringResource("ERROR_MSG_DEADLINE_NULL", ClientCulture));


            string Login = (string)Parameters[CServerFunctionParams.CONST_FUNC_PARAM_LOGIN];
            string Password = (string)Parameters[CServerFunctionParams.CONST_FUNC_PARAM_PASSWORD];
            string Passhash = CSecurityHelper.sGeneratePasshash(Login, Password);
            DateTime Deadline = (DateTime)Parameters[CServerFunctionParams.CONST_FUNC_PARAM_SESSION_DEADLINE];            

            string DeviceID = "";
            string AuthToken = "";

            CSystemUser User = CSystemUser.sGetUserByLoginPasshash(Login, Password, Passhash, CFunctionExecutionEnvironment.sGetCurrentProvider());
            if (User == null)
                return this._compileResult(EnFunctionResultType.EError, Parameters, CGlobalizationHelper.sGetStringResource("ERROR_MSG_USER_LOGIN_PASS_NULL", ClientCulture));

            User.GetPolicies(CFunctionExecutionEnvironment.sGetCurrentProvider());
            if (User.Status != EnMetaobjectStatus.EEnabled)
                return this._compileResult(EnFunctionResultType.EError, Parameters, CGlobalizationHelper.sGetStringResource("ERROR_MSG_USER_DISABLED", ClientCulture));
            if (!User.PolicyAllowEditSessionsList())
                return this._compileResult(EnFunctionResultType.EError, Parameters, CGlobalizationHelper.sGetStringResource("ERROR_MSG_USER_NOT_ALLOWED_CREATE_SESSIONS", ClientCulture));

            /*if (Parameters.ContainsKey(CServerFunctionParams.CONST_FUNC_PARAM_DEVICE_ID))
            {
                DeviceID = (string)Parameters[CServerFunctionParams.CONST_FUNC_PARAM_DEVICE_ID];
                Device = new CClientDevice(Guid.Parse(DeviceID), CFunctionExecutionEnvironment.sGetCurrentProvider());
                if (Device.Key == -1)
                    return this._compileResult(EnFunctionResultType.EError, Parameters, CGlobalizationHelper.sGetStringResource("ERROR_MSG_DEVICE_ID_NULL", ClientCulture));
            }
            else
            {
                if (!User.PolicyAllowEditDevicesList())
                    return this._compileResult(EnFunctionResultType.EError, Parameters, CGlobalizationHelper.sGetStringResource("ERROR_MSG_USER_NOT_ALLOWED_CREATE_DEVICES", ClientCulture));
                if (!Parameters.ContainsKey(CServerFunctionParams.CONST_FUNC_PARAM_DEVICE_NAME))
                    return this._compileResult(EnFunctionResultType.EError, Parameters, CGlobalizationHelper.sGetStringResource("ERROR_MSG_DEVICE_NAME_EMPTY", ClientCulture));
                if (!Parameters.ContainsKey(CServerFunctionParams.CONST_FUNC_PARAM_DEVICE_MAC))
                    return this._compileResult(EnFunctionResultType.EError, Parameters, CGlobalizationHelper.sGetStringResource("ERROR_MSG_DEVICE_MAC_EMPTY", ClientCulture));

                string DeviceName = (string)Parameters[CServerFunctionParams.CONST_FUNC_PARAM_DEVICE_NAME];
                string DeviceMAC = (string)Parameters[CServerFunctionParams.CONST_FUNC_PARAM_DEVICE_MAC];
                DeviceID = Guid.NewGuid().ToString();

                Device = new CClientDevice(CFunctionExecutionEnvironment.sGetCurrentProvider());
                Device.Name = DeviceName;
                Device.ID = Guid.Parse(DeviceID);
                Device.MACAddress = DeviceMAC;
                Device.Type = EnClientDeviceType.EExternal;
                Device.Parent = CEmbeddedObjectsConsts.CONST_FOLDER_DEVICES_KEY;
                var R = Device.ObjectInsert(CFunctionExecutionEnvironment.sGetCurrentProvider());
                if (R != -1)
                    return this._compileResult(EnFunctionResultType.EError, Parameters, CGlobalizationHelper.sGetStringResource("ERROR_MSG_USER_NOT_ALLOWED_CREATE_DEVICES", ClientCulture));

                List<CSystemUserGroup> Groups = CSystemUserGroup.sGetAllGroups(CFunctionExecutionEnvironment.sGetCurrentProvider());
                foreach (CSystemUserGroup Group in Groups)
                {
                    var Rights = 1;
                    if (Group.ID.ToString().ToUpper() == CEmbeddedSecurityConsts.CONST_USER_GROUP_ADMINISTRATORS_ID)
                    {
                        Rights = 3;
                    }
                    if (Group.ID.ToString().ToUpper() == CEmbeddedSecurityConsts.CONST_USER_GROUP_USERS_ID)
                    {
                        Rights = 3;
                    }

                    CMetaobjectSecurityRecord Record = new CMetaobjectSecurityRecord()
                    {
                        MetaobjectKey = Device.Key,
                        Rights = Rights,
                        UserKey = Group.Key
                        
                    };
                    R = Record.RecordInsert(CFunctionExecutionEnvironment.sGetCurrentProvider());
                    if (R != -1)
                        return this._compileResult(EnFunctionResultType.EError, Parameters, CGlobalizationHelper.sGetStringResource("ERROR_MSG_USER_NOT_ALLOWED_CREATE_SEC_RECORD", ClientCulture));
                }
            }*/

            AuthToken = "";
            CSystemUserSession Session = new CSystemUserSession();
            Session.DeadLine = Deadline;
            Session.UserKey = User.Key;
            Session.ID = Guid.NewGuid();
            if (Session.SessionInsert(CFunctionExecutionEnvironment.sGetCurrentProvider()) != -1)
                return this._compileResult(EnFunctionResultType.EError, Parameters, CGlobalizationHelper.sGetStringResource("ERROR_MSG_USER_NOT_ALLOWED_CREATE_SESSIONS", ClientCulture));

            Result.InputParameters = Parameters;
            Result.ResultType = EnFunctionResultType.ESuccess;
            Result.Message = CGlobalizationHelper.sGetStringResource("ERROR_MSG_USER_AUTHENTICATED", ClientCulture);
            Result.Content = "DeviceID=" + DeviceID + ";AuthToken=" + AuthToken + ";SessionDeadline=" + Deadline.ToString("G");
            return Result;
        }
        public static List<CSystemUserSession> sGetSessionsByUser(decimal UserKey, IDatabaseProvider Provider)
        {
            List<CSystemUserSession> R = new List<CSystemUserSession>();
            
            Hashtable Params = new Hashtable();
            Params.Add(CDBConst.CONST_TABLE_FIELD_SESSION_USER, UserKey);

            var SQL = "SELECT " + CDBConst.CONST_TABLE_FIELD_SESSION_USER + ", " + CDBConst.CONST_TABLE_FIELD_SESSION_DEADLINE;
            SQL += ", " + CDBConst.CONST_TABLE_FIELD_SESSION_KEY + ", " + CDBConst.CONST_TABLE_FIELD_SESSION_ID + ", " + CDBConst.CONST_TABLE_FIELD_SESSION_STATUS + ", " + CDBConst.CONST_TABLE_FIELD_SESSION_VARIABLES;
            SQL += ", " + CDBConst.CONST_TABLE_FIELD_SESSION_TYPE;
            SQL += " FROM " + CDBConst.CONST_TABLE_SESSION;
            SQL += " WHERE " + CDBConst.CONST_TABLE_FIELD_SESSION_USER + " = @p" + CDBConst.CONST_TABLE_FIELD_SESSION_USER;

            var T = Provider.QueryGetData(SQL, false, Params);
            if (T == null || T.Rows.Count == 0)
                return R;

            for (int i = 0; i < T.Rows.Count; i++)
            {
                var Session = new CSystemUserSession();
                Session.UserKey = T.Rows[i][0].PostProcessDatabaseValue<decimal>(CDBConst.CONST_OBJECT_EMPTY_KEY);
                Session.DeadLine = T.Rows[i][1].PostProcessDatabaseValue<DateTime>(DateTime.Now);
                Session.Key = T.Rows[i][3].PostProcessDatabaseValue<decimal>(CDBConst.CONST_OBJECT_EMPTY_KEY);
                Session.ID = Guid.Parse(T.Rows[i][4].PostProcessDatabaseValue<string>(""));
                Session.Status = T.Rows[i][5].PostProcessDatabaseValue<EnSessionStatus>(EnSessionStatus.EEnabled);
                Session.Type = T.Rows[i][7].PostProcessDatabaseValue<EnSessionType>(EnSessionType.EWeb);

                byte[] Data = T.Rows[0][6].PostProcessDatabaseValue<byte[]>(new byte[0]);
                Session.Variables = Data.ToDataStream().DeserializeBinaryStream<Hashtable>();
                R.Add(Session);
            }
            
            return R;

        }