@ApiOperation(value = "Update a user", tags = { "Users" }, notes = "All request values are optional. "
            + "For example, you can only include the firstName attribute in the request body JSON-object, only updating the firstName of the user, leaving all other fields unaffected. "
            + "When an attribute is explicitly included and is set to null, the user-value will be updated to null. "
            + "Example: {\"firstName\" : null} will clear the firstName of the user).")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "Indicates the user was updated."),
            @ApiResponse(code = 404, message = "Indicates the requested user was not found."),
            @ApiResponse(code = 409, message = "Indicates the requested user was updated simultaneously.")
    })
    @PutMapping(value = "/identity/users/{userId}", produces = "application/json")
    public UserResponse updateUser(@ApiParam(name = "userId") @PathVariable String userId, @RequestBody UserRequest userRequest) {
        User user = getUserFromRequest(userId);
        if (userRequest.isEmailChanged()) {
            user.setEmail(userRequest.getEmail());
        }
        if (userRequest.isFirstNameChanged()) {
            user.setFirstName(userRequest.getFirstName());
        }
        if (userRequest.isDisplayNameChanged()) {
            user.setDisplayName(userRequest.getDisplayName());
        }
        if (userRequest.isLastNameChanged()) {
            user.setLastName(userRequest.getLastName());
        }
        if (userRequest.isPasswordChanged()) {
            user.setPassword(userRequest.getPassword());
            identityService.updateUserPassword(user);
        } else {
            identityService.saveUser(user);
        }

        return restResponseFactory.createUserResponse(user, false);
    }
@Test
    public void testUpdateUser() throws Exception {
        User savedUser = null;
        try {
            User newUser = identityService.newUser("testuser");
            newUser.setFirstName("Fred");
            newUser.setLastName("McDonald");
            newUser.setEmail("no-reply@flowable.org");
            identityService.saveUser(newUser);
            savedUser = newUser;

            ObjectNode taskUpdateRequest = objectMapper.createObjectNode();
            taskUpdateRequest.put("firstName", "Tijs");
            taskUpdateRequest.put("lastName", "Barrez");
            taskUpdateRequest.put("displayName", "Tijs Barrez");
            taskUpdateRequest.put("email", "no-reply@flowable.org");
            taskUpdateRequest.put("password", "updatedpassword");

            HttpPut httpPut = new HttpPut(SERVER_URL_PREFIX + RestUrls.createRelativeResourceUrl(RestUrls.URL_USER, newUser.getId()));
            httpPut.setEntity(new StringEntity(taskUpdateRequest.toString()));
            CloseableHttpResponse response = executeRequest(httpPut, HttpStatus.SC_OK);
            JsonNode responseNode = objectMapper.readTree(response.getEntity().getContent());
            closeResponse(response);
            assertThat(responseNode).isNotNull();
            assertThatJson(responseNode)
                    .when(Option.IGNORING_EXTRA_FIELDS)
                    .isEqualTo("{"
                            + "id: 'testuser',"
                            + "firstName: 'Tijs',"
                            + "lastName: 'Barrez',"
                            + "displayName: 'Tijs Barrez',"
                            + "email: 'no-reply@flowable.org',"
                            + "url: '" + SERVER_URL_PREFIX + RestUrls.createRelativeResourceUrl(RestUrls.URL_USER, newUser.getId()) + "'"
                            + "}");

            // Check user is updated in Flowable
            newUser = identityService.createUserQuery().userId(newUser.getId()).singleResult();
            assertThat(newUser.getLastName()).isEqualTo("Barrez");
            assertThat(newUser.getFirstName()).isEqualTo("Tijs");
            assertThat(newUser.getDisplayName()).isEqualTo("Tijs Barrez");
            assertThat(newUser.getEmail()).isEqualTo("no-reply@flowable.org");
            assertThat(newUser.getPassword()).isEqualTo("updatedpassword");

        } finally {

            // Delete user after test fails
            if (savedUser != null) {
                identityService.deleteUser(savedUser.getId());
            }
        }
    }