/// <summary>
        /// Change password
        /// </summary>
        /// <param name="request">Request</param>
        /// <returns>Result</returns>
        public virtual ChangePasswordResult ChangePassword(ChangePasswordRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            var result = new ChangePasswordResult();

            if (string.IsNullOrWhiteSpace(request.Email))
            {
                result.AddError("Email is not entered");
                return(result);
            }
            if (string.IsNullOrWhiteSpace(request.NewPassword))
            {
                result.AddError("Password is not entered");
                return(result);
            }

            var user = _userService.GetUserByEmail(request.Email);

            if (user == null)
            {
                result.AddError("The specified email could not be found");
                return(result);
            }

            if (request.ValidateRequest)
            {
                //request isn't valid
                if (!PasswordsMatch(_userService.GetCurrentPassword(user.Id), request.OldPassword))
                {
                    result.AddError("Old password doesn't match");
                    return(result);
                }
            }

            //check for duplicates
            if (_userSettings.UnduplicatedPasswordsNumber > 0)
            {
                //get some of previous passwords
                var previousPasswords = _userService.GetUserPasswords(user.Id, passwordsToReturn: _userSettings.UnduplicatedPasswordsNumber);

                var newPasswordMatchesWithPrevious = previousPasswords.Any(password => PasswordsMatch(password, request.NewPassword));
                if (newPasswordMatchesWithPrevious)
                {
                    result.AddError("You entered the password that is the same as one of the last passwords you used. Please create a new password.");
                    return(result);
                }
            }

            //at this point request is valid
            var userPassword = new UserPassword
            {
                User           = user,
                PasswordFormat = request.NewPasswordFormat,
                CreatedOn      = DateTime.Now
            };

            switch (request.NewPasswordFormat)
            {
            case PasswordFormat.Clear:
                userPassword.Password = request.NewPassword;
                break;

            case PasswordFormat.Encrypted:
                userPassword.Password = _encryptionService.EncryptText(request.NewPassword);
                break;

            case PasswordFormat.Hashed:
            {
                var saltKey = _encryptionService.CreateSaltKey(SALT_KEY_SIZE);
                userPassword.PasswordSalt = saltKey;
                userPassword.Password     = _encryptionService.CreatePasswordHash(request.NewPassword, saltKey, _userSettings.HashedPasswordFormat);
            }
            break;
            }
            _userService.InsertUserPassword(userPassword);

            //publish event
            _eventPublisher.Publish(new UserPasswordChangedEvent(userPassword));

            return(result);
        }