class BaseUserEditorWorkflow implements IsWidget {

    protected void doSave() {
        assert user != null;

        final boolean isValid = userEditorDriver.flush();
        this.user = userEditorDriver.getValue();

        if (isValid) {
            final RemoteCallback<User> assignGroupsCallback =
                    user1 -> doAssignGroups(() -> doAssignRoles(() -> {
                        hideLoadingBox();
                        BaseUserEditorWorkflow.this.isDirty = false;
                        // Ask for the user's password if user is just created.
                        final String id = user1.getIdentifier();
                        afterSave(id);
                    }));

            // Update the wrapped user instance from the modifiable one and assign updated groups if update op is successful.
            showLoadingBox();
            doSaveRemoteServiceCall(assignGroupsCallback);
        } else {
            throw new RuntimeException("User must be valid before updating it.");
        }
    }

    public  BaseUserEditorWorkflow(final ClientUserSystemManager userSystemManager,
                                  final Event<OnErrorEvent> errorEvent,
                                  final Event<NotificationEvent> workbenchNotification,
                                  final Event<DeleteUserEvent> deleteUserEvent,
                                  final Event<SaveUserEvent> saveUserEvent,
                                  final ConfirmBox confirmBox,
                                  final UserEditor userEditor,
                                  final UserEditorDriver userEditorDriver,
                                  final ChangePassword changePassword,
                                  final LoadingBox loadingBox,
                                  final EntityWorkflowView view);

}