/// <summary>
            /// Change password for the user.
            /// </summary>
            /// <param name="request">The device activation request.</param>
            /// <returns>The device activation response.</returns>
            private static StaffChangePasswordRealtimeResponse ChangePassword(UserChangePasswordRealtimeRequest request)
            {
                string staffId = request.StaffId;

                if (string.IsNullOrWhiteSpace(staffId))
                {
                    throw new UserAuthorizationException(SecurityErrors.Microsoft_Dynamics_Commerce_Runtime_ChangePasswordFailed, "Staff Id is not valid.");
                }

                TransactionService.TransactionServiceClient transactionService = new TransactionService.TransactionServiceClient(request.RequestContext);

                string                  newPasswordHash;
                string                  newPasswordSalt;
                string                  newPasswordHashAlgorithm;
                DateTimeOffset          newPasswordLastChangedDateTime;
                AuthenticationOperation newPasswordLastUpdatedOperation;

                transactionService.StaffChangePassword(
                    staffId,
                    request.OldPassword,
                    request.NewPassword,
                    changePassword: false,
                    newPasswordHash: out newPasswordHash,
                    newPasswordSalt: out newPasswordSalt,
                    newPasswordHashAlgorithm: out newPasswordHashAlgorithm,
                    newPasswordLastChangedDateTime: out newPasswordLastChangedDateTime,
                    newPasswordLastUpdatedOperation: out newPasswordLastUpdatedOperation);

                return(new StaffChangePasswordRealtimeResponse(newPasswordHash, newPasswordSalt, newPasswordHashAlgorithm, newPasswordLastChangedDateTime, newPasswordLastUpdatedOperation));
            }
            /// <summary>
            /// Change password for the user.
            /// </summary>
            /// <param name="request">The device activation request.</param>
            /// <returns>The device activation response.</returns>
            private static Response ChangePassword(UserChangePasswordRealtimeRequest request)
            {
                ThrowIf.Null(request, "request");

                long   channelId = request.RequestContext.GetPrincipal().ChannelId;
                string staffId   = request.StaffId;

                // Get employee salt and password hash algorithm.
                GetEmployeePasswordCryptoInfoDataRequest employeePasswordCryptoInfoRequest = new GetEmployeePasswordCryptoInfoDataRequest(channelId, staffId);
                var    passwordCryptoInfo = request.RequestContext.Execute <SingleEntityDataServiceResponse <EmployeePasswordCryptoInfo> >(employeePasswordCryptoInfoRequest).Entity;
                string salt = passwordCryptoInfo.PasswordSalt ?? string.Empty;
                string passwordHashAlgorithm = passwordCryptoInfo.PasswordHashAlgorithm;

                if (string.IsNullOrEmpty(passwordHashAlgorithm))
                {
                    // get hash algorithm from the transaction service profile.
                    var getTransactionServiceProfileDataRequest         = new GetTransactionServiceProfileDataRequest();
                    TransactionServiceProfile transactionServiceProfile = request.RequestContext.Execute <SingleEntityDataServiceResponse <TransactionServiceProfile> >(
                        getTransactionServiceProfileDataRequest).Entity;
                    passwordHashAlgorithm = transactionServiceProfile.StaffPasswordHash;
                }

                // hash old password
                HashDataServiceRequest hashDataServiceRequest = new HashDataServiceRequest(request.OldPassword, passwordHashAlgorithm, request.StaffId, salt);
                string oldPasswordHash = request.RequestContext.Execute <HashDataServiceResponse>(hashDataServiceRequest).Data;

                // check if old password is correct
                EmployeeLogOnStoreDataRequest employeeDataRequest = new EmployeeLogOnStoreDataRequest(
                    channelId,
                    staffId,
                    oldPasswordHash,
                    new ColumnSet());

                if (request.RequestContext.Execute <SingleEntityDataServiceResponse <Employee> >(employeeDataRequest).Entity == null)
                {
                    // SecurityErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidPassword is used internally to identify when user provides incorrect password
                    // here we make sure this is not surfaced outside of the runtime, so there is no information disclosure
                    throw new UserAuthenticationException(SecurityErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidAuthenticationCredentials, "Incorrect user name or password.");
                }

                // hash new password
                hashDataServiceRequest = new HashDataServiceRequest(request.NewPassword, passwordHashAlgorithm, request.StaffId, salt);
                string newPasswordHash = request.RequestContext.Execute <HashDataServiceResponse>(hashDataServiceRequest).Data;

                // return new password hash + salt
                return(new StaffChangePasswordRealtimeResponse(newPasswordHash, salt, passwordHashAlgorithm, DateTime.UtcNow, AuthenticationOperation.ChangePassword));
            }