diff --git a/README.md b/README.md
index 39fdc0490667f2f9dee0a5e4f19c998d1adcfb6b..7ede578edbf2f4223689ced780dab4dea7cc8f29 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # Service Metadata Publishing
 
-## Continous Integration
+## Continuous Integration
 
 [https://webgate.ec.europa.eu/CITnet/bamboo/browse/EDELIVERY-SMPDEV]
 
diff --git a/smp-angular/src/app/app.component.html b/smp-angular/src/app/app.component.html
index 09fffd200c508e1c7182b5263bab6510564e30ae..283cf208016111a2a3f210921b215866c5b760f2 100644
--- a/smp-angular/src/app/app.component.html
+++ b/smp-angular/src/app/app.component.html
@@ -10,32 +10,31 @@
     </div>
 
     <button mat-raised-button class="sideNavButton" [routerLink]="['/']" id="sidebar_search_id">
-      <mat-icon matTooltip="Search" matTooltipDisabled="{{fullMenu}}" matTooltipDisabled="right">search</mat-icon>
+      <mat-icon matTooltip="Search" matTooltipDisabled="{{fullMenu}}" [matTooltipPosition]="'right'">search</mat-icon>
       <span>Search</span>
     </button>
-    <button mat-raised-button class="sideNavButton" *ngIf="isCurrentUserSMPAdmin() || isCurrentUserServiceGroupAdmin()"  [routerLink]="['/edit']" id="sidebar_edit_id">
-      <mat-icon matTooltip="Edit" matTooltipDisabled="{{fullMenu}}" matTooltipDisabled="right">edit</mat-icon>
+    <button mat-raised-button class="sideNavButton" *ngIf="isCurrentUserSMPAdmin() || isCurrentUserServiceGroupAdmin()" [routerLink]="['/edit']" id="sidebar_edit_id">
+      <mat-icon matTooltip="Edit" matTooltipDisabled="{{fullMenu}}" [matTooltipPosition]="'right'">edit</mat-icon>
       <span>Edit</span>
     </button>
-    <button mat-raised-button class="sideNavButton" [routerLink]="['/domain']"  *ngIf="isCurrentUserSystemAdmin()" id="sidebar_domain_id">
-      <mat-icon matTooltip="Domain" matTooltipDisabled="{{fullMenu}}" matTooltipDisabled="right">domain</mat-icon>
+    <button mat-raised-button class="sideNavButton" [routerLink]="['/domain']" *ngIf="isCurrentUserSystemAdmin()" id="sidebar_domain_id">
+      <mat-icon matTooltip="Domain" matTooltipDisabled="{{fullMenu}}" [matTooltipPosition]="'right'">domain</mat-icon>
       <span>Domain</span>
     </button>
 
     <!-- button mat-raised-button class="sideNavButton" [routerLink]="['/user']" *ngIf="hasAdmin()" id="user_id" -->
-    <button mat-raised-button class="sideNavButton" [routerLink]="['/user']" *ngIf="isCurrentUserSystemAdmin()"  id="sidebar_user_id">
-      <mat-icon matTooltip="Users" matTooltipDisabled="{{fullMenu}}" matTooltipDisabled="right">people</mat-icon>
+    <button mat-raised-button class="sideNavButton" [routerLink]="['/user']" *ngIf="isCurrentUserSystemAdmin()" id="sidebar_user_id">
+      <mat-icon matTooltip="Users" matTooltipDisabled="{{fullMenu}}" [matTooltipPosition]="'right'">people</mat-icon>
       <span>Users</span>
     </button>
 
-
     <div class="collapse-button">
       <button *ngIf="fullMenu" mat-raised-button id="expand_id" (click)="toggleMenu()">
-        <mat-icon matTooltip="Collapse" matTooltipDisabled="right">chevron_left</mat-icon>
+        <mat-icon matTooltip="Collapse" [matTooltipPosition]="'right'">chevron_left</mat-icon>
       </button>
 
       <button *ngIf="!fullMenu" mat-raised-button id="collapse_id" (click)="toggleMenu()">
-        <mat-icon matTooltip="Esxpand" matTooltipDisabled="right">chevron_right</mat-icon>
+        <mat-icon matTooltip="Expand" [matTooltipPosition]="'right'">chevron_right</mat-icon>
       </button>
     </div>
 
@@ -61,8 +60,6 @@
     <alert style=" left:220px; top:0;right:0;z-index: 500"></alert>
 
     <div  id="sandwichMenuHolder" style="z-index: 500">
-
-
       <div id="sandwichMenu">
 
         <a *ngIf="!currentUser" [routerLink]="['/login']" > Login   </a>
@@ -73,10 +70,9 @@
         </button>
 
         <mat-menu x-position="before" #settingsMenu="matMenu">
-
           <div *ngIf="currentUser">
 
-            <button mat-menu-item disabled="true" id="currentuser_id">
+            <button mat-menu-item id="currentuser_id" (click)="editCurrentUser()">
               <mat-icon>person</mat-icon>
               <span>{{currentUser}}</span>
             </button>
@@ -96,7 +92,6 @@
               <span>Not logged in</span>
             </button>
           </div>
-
         </mat-menu>
       </div>
     </div>
@@ -104,7 +99,5 @@
     <div fxFill="100" id="routerHolder" style="min-height: 100%" >
         <router-outlet></router-outlet>
     </div>
-
   </div>
-
 </mat-sidenav-container>
diff --git a/smp-angular/src/app/app.component.ts b/smp-angular/src/app/app.component.ts
index 7e0df476180964a7009032f2c46a78a7ac63f5d7..a1857739995029e5ece4b7e9e854a961cc304c0c 100644
--- a/smp-angular/src/app/app.component.ts
+++ b/smp-angular/src/app/app.component.ts
@@ -1,35 +1,37 @@
-import {Component, OnInit, ViewChild} from '@angular/core';
+import {Component, ViewChild} from '@angular/core';
 import {SecurityService} from './security/security.service';
-import {Router, RouterOutlet} from '@angular/router';
-import {SecurityEventService} from './security/security-event.service';
-import {Title} from '@angular/platform-browser';
-import {HttpClient, HttpResponse} from '@angular/common/http';
+import {Router} from '@angular/router';
 import {Authority} from "./security/authority.model";
-
+import {AlertService} from "./alert/alert.service";
+import {MatDialog, MatDialogRef} from "@angular/material";
+import {GlobalLookups} from "./common/global-lookups";
+import {UserController} from "./user/user-controller";
+import {HttpClient} from "@angular/common/http";
+import {SearchTableEntityStatus} from "./common/search-table/search-table-entity-status.model";
+import {SmpConstants} from "./smp.constants";
+import {UserService} from "./user/user.service";
+import {UserDetailsDialogMode} from "./user/user-details-dialog/user-details-dialog.component";
 
 @Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
 })
-export class AppComponent implements OnInit {
+export class AppComponent {
 
-  _currentUser: string;
   fullMenu: boolean = true;
   menuClass: string = this.fullMenu ? "menu-expanded" : "menu-collapsed";
-
-  @ViewChild(RouterOutlet)
-  outlet: RouterOutlet;
-
-  constructor(private securityService: SecurityService,
-              private router: Router,
-              private securityEventService: SecurityEventService,
-              private http: HttpClient,
-              private titleService: Title) {
-
-  }
-
-  ngOnInit() {
+  userController: UserController;
+
+  constructor(
+    private securityService: SecurityService,
+    private router: Router,
+    private http: HttpClient,
+    private dialog: MatDialog,
+    private lookups: GlobalLookups,
+    private userService: UserService,
+  ) {
+    this.userController = new UserController(this.http, this.lookups, this.dialog);
   }
 
   isCurrentUserSystemAdmin(): boolean {
@@ -39,44 +41,55 @@ export class AppComponent implements OnInit {
   isCurrentUserSMPAdmin(): boolean {
     return this.securityService.isCurrentUserInRole([ Authority.SMP_ADMIN]);
   }
+
   isCurrentUserServiceGroupAdmin(): boolean {
     return this.securityService.isCurrentUserInRole([ Authority.SERVICE_GROUP_ADMIN]);
   }
 
+  editCurrentUser() {
+    const formRef: MatDialogRef<any> = this.userController.newDialog({
+      data: {mode: UserDetailsDialogMode.PREFERENCES_MODE, row: this.securityService.getCurrentUser()}
+    });
+    formRef.afterClosed().subscribe(result => {
+      if (result) {
+        const user = {...formRef.componentInstance.getCurrent(), status: SearchTableEntityStatus.UPDATED};
+        this.userService.updateUser(user);
+      }
+    });
+  }
+
   get currentUser(): string {
     let user = this.securityService.getCurrentUser();
     return user ? user.username : "";
   }
 
-
   get currentUserRoleDescription(): string {
       if (this.securityService.isCurrentUserSystemAdmin()){
         return "System administrator";
       } else if (this.securityService.isCurrentUserSMPAdmin()){
         return "SMP administrator";
       } else if (this.securityService.isCurrentUserServiceGroupAdmin()){
-        return "Service group administrator"
+        return "Service group administrator";
       }
       return "";
   }
 
-
   logout(event: Event): void {
     event.preventDefault();
     this.router.navigate(['/search']).then((ok) => {
       if (ok) {
         this.securityService.logout();
       }
-    })
+    });
   }
 
   toggleMenu() {
-    this.fullMenu = !this.fullMenu
-    this.menuClass = this.fullMenu ? "menu-expanded" : "menu-collapsed"
+    this.fullMenu = !this.fullMenu;
+    this.menuClass = this.fullMenu ? "menu-expanded" : "menu-collapsed";
     setTimeout(() => {
-      var evt = document.createEvent("HTMLEvents")
-      evt.initEvent('resize', true, false)
-      window.dispatchEvent(evt)
+      var evt = document.createEvent("HTMLEvents");
+      evt.initEvent('resize', true, false);
+      window.dispatchEvent(evt);
     }, 500)
     //ugly hack but otherwise the ng-datatable doesn't resize when collapsing the menu
     //alternatively this can be tried (https://github.com/swimlane/ngx-datatable/issues/193) but one has to implement it on every page
diff --git a/smp-angular/src/app/app.module.ts b/smp-angular/src/app/app.module.ts
index 0caea69b181fd646e93e658b01fcb635c036e450..f127a35eeae2357dd1b2fcabfd511058cc7e0b57 100644
--- a/smp-angular/src/app/app.module.ts
+++ b/smp-angular/src/app/app.module.ts
@@ -75,6 +75,8 @@ import {ServiceGroupExtensionWizardDialogComponent} from "./service-group-edit/s
 import {ServiceMetadataWizardDialogComponent} from "./service-group-edit/service-metadata-wizard-dialog/service-metadata-wizard-dialog.component";
 import {ConfirmationDialogComponent} from "./common/confirmation-dialog/confirmation-dialog.component";
 import {SpinnerComponent} from "./common/spinner/spinner.component";
+import {UserService} from "./user/user.service";
+import {UserDetailsService} from "./user/user-details-dialog/user-details.service";
 
 @NgModule({
   declarations: [
@@ -164,6 +166,8 @@ import {SpinnerComponent} from "./common/spinner/spinner.component";
     CertificateService,
     GlobalLookups,
     DatePipe,
+    UserService,
+    UserDetailsService,
     {
       provide: ExtendedHttpClient,
       useFactory: extendedHttpClientCreator,
diff --git a/smp-angular/src/app/security/security.service.ts b/smp-angular/src/app/security/security.service.ts
index 3b28efdd209be643fe77ed6dd5e0f7cd25caffb7..3a80585ce52b1d9d7e8c23d2ff7f5e22689cf147 100644
--- a/smp-angular/src/app/security/security.service.ts
+++ b/smp-angular/src/app/security/security.service.ts
@@ -23,8 +23,7 @@ export class SecurityService {
       }),
       { headers })
       .subscribe((response: string) => {
-          this.populateLocalStorage(JSON.stringify(response));
-          this.securityEventService.notifyLoginSuccessEvent(response);
+          this.updateUserDetails(response);
         },
         (error: any) => {
           this.securityEventService.notifyLoginErrorEvent(error);
@@ -32,8 +31,6 @@ export class SecurityService {
   }
 
   logout() {
-    console.log('Logging out');
-   // this.domainService.resetDomain();
     this.http.delete(SmpConstants.REST_SECURITY_AUTHENTICATION).subscribe((res: Response) => {
         this.clearLocalStorage();
         this.securityEventService.notifyLogoutSuccessEvent(res);
@@ -116,6 +113,11 @@ export class SecurityService {
     return subject.asObservable();
   }
 
+  updateUserDetails(userDetails) {
+    this.populateLocalStorage(JSON.stringify(userDetails));
+    this.securityEventService.notifyLoginSuccessEvent(userDetails);
+  }
+
   private populateLocalStorage(userDetails: string) {
     localStorage.setItem(this.LOCAL_STORAGE_KEY_CURRENT_USER, userDetails);
   }
diff --git a/smp-angular/src/app/service-group-edit/service-metadata-wizard-dialog/service-metadata-wizard-dialog.component.ts b/smp-angular/src/app/service-group-edit/service-metadata-wizard-dialog/service-metadata-wizard-dialog.component.ts
index c52d10d668754a98aac2b7cf7c870293ed20c2c4..ff3fe7f49a9c6c38aa0176a224dcff472cd9200d 100644
--- a/smp-angular/src/app/service-group-edit/service-metadata-wizard-dialog/service-metadata-wizard-dialog.component.ts
+++ b/smp-angular/src/app/service-group-edit/service-metadata-wizard-dialog/service-metadata-wizard-dialog.component.ts
@@ -4,7 +4,7 @@ import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
 import {HttpClient} from "@angular/common/http";
 import {SmpConstants} from "../../smp.constants";
 import {ServiceMetadataEditRo} from "../service-metadata-edit-ro.model";
-
+import {CertificateService} from "../../user/certificate.service";
 
 @Component({
   selector: 'service-metadata-wizard-dialog',
@@ -17,22 +17,22 @@ export class ServiceMetadataWizardDialogComponent {
   static readonly EDIT_MODE = 'Edit ServiceMetadata XML';
 
   editMode: boolean;
-  formTitle: string;
   current: ServiceMetadataEditRo & { confirmation?: string };
   dialogForm: FormGroup;
   certificateValidationMessage: string;
   isCertificateValid: string;
   selectedFile: File;
 
-  dummyXML: string = "<!-- Custom element is mandatory by OASIS SMP schema.\n    Replace following element with your XML structure. -->\n<ext:example xmlns:ext=\"http://my.namespace.eu\">my mandatory content</ext:example>"
-
+  // dummyXML: string = "<!-- Custom element is mandatory by OASIS SMP schema.\n    Replace following element with your XML structure. -->\n<ext:example xmlns:ext=\"http://my.namespace.eu\">my mandatory content</ext:example>"
 
-  constructor( protected http: HttpClient,
-               public dialogRef: MatDialogRef<ServiceMetadataWizardDialogComponent>,
-              private dialogFormBuilder: FormBuilder) {
+  constructor(
+    private http: HttpClient,
+    private dialogRef: MatDialogRef<ServiceMetadataWizardDialogComponent>,
+    private dialogFormBuilder: FormBuilder,
+    private certificateService: CertificateService,
+  ) {
 
     this.dialogForm = dialogFormBuilder.group({
-
       'documentIdentifier': new FormControl({value: ''}, [Validators.required]),
       'documentIdentifierScheme': new FormControl({value: ''}, null),
       'processScheme': new FormControl({value: ''}, [Validators.required]),
@@ -49,14 +49,12 @@ export class ServiceMetadataWizardDialogComponent {
 
   onUpload() {
     // this.http is the injected HttpClient
-    this.http.post(SmpConstants.REST_CERTIFICATE, this.selectedFile)
+    this.certificateService.uploadCertificate$(this.selectedFile)
       .subscribe(event => {
-
         console.log(event); // handle event here
       });
   }
 
-
   getExtensionXML() {
     /*
     var xmlString = '<Extension xmlns="http://docs.oasis-open.org/bdxr/ns/SMP/2016/05">'
@@ -79,6 +77,4 @@ export class ServiceMetadataWizardDialogComponent {
       .replace(/>/g, "&gt;")
       .replace(/"/g, "&quot;");
   }
-
-
 }
diff --git a/smp-angular/src/app/smp.constants.ts b/smp-angular/src/app/smp.constants.ts
index cdded6c53ba93102b76dec3f6ca96984696a77c9..ad7858ded07b5d6992669106f4d4cb785aa28acd 100644
--- a/smp-angular/src/app/smp.constants.ts
+++ b/smp-angular/src/app/smp.constants.ts
@@ -9,8 +9,6 @@ export class SmpConstants {
   public static readonly REST_SECURITY_USER = 'rest/security/user';
   public static readonly REST_APPLICATION = 'rest/application/info';
 
-
-  public static readonly REST_CERTIFICATE = `${SmpConstants.REST_USER}/certdata`;
   public static readonly REST_USER_VALIDATE_DELETE = `${SmpConstants.REST_USER}/validateDelete`;
   public static readonly REST_DOMAIN_VALIDATE_DELETE = `${SmpConstants.REST_DOMAIN}/validateDelete`;
   public static readonly REST_SERVICE_GROUP_EXTENSION = `${SmpConstants.REST_EDIT}/extension`;
diff --git a/smp-angular/src/app/user/certificate.service.ts b/smp-angular/src/app/user/certificate.service.ts
index 7c969c1800b73f8c0ae1ce43fce1d1e62d322f30..30508bf7b4d4ddb1af24ca42fef359410136f86e 100644
--- a/smp-angular/src/app/user/certificate.service.ts
+++ b/smp-angular/src/app/user/certificate.service.ts
@@ -3,13 +3,22 @@ import {Observable} from 'rxjs';
 import {CertificateRo} from './certificate-ro.model';
 import {HttpClient} from '@angular/common/http';
 import {SmpConstants} from "../smp.constants";
+import {SecurityService} from "../security/security.service";
+import {User} from "../security/user.model";
 
 @Injectable()
 export class CertificateService {
 
-  constructor(private http: HttpClient) {}
+  constructor(
+    private http: HttpClient,
+    private securityService: SecurityService,
+  ) { }
 
   uploadCertificate$(payload): Observable<CertificateRo> {
-    return this.http.post<CertificateRo>(SmpConstants.REST_CERTIFICATE, payload);
+    // The user identifier below belongs to the currently logged in user and it may or may not be the same as the
+    // identifier of the user being modified (e.g. a normal user editing his own details vs. a system administrator
+    // adding or editing another user)
+    const currentUser: User = this.securityService.getCurrentUser();
+    return this.http.post<CertificateRo>(`${SmpConstants.REST_USER}/${currentUser.id}/certdata`, payload);
   }
 }
diff --git a/smp-angular/src/app/user/user-controller.ts b/smp-angular/src/app/user/user-controller.ts
index 856d2173b9b321680cc7420fc26ab7961aaedb70..76c18573f835437a2e5536fe662d6501f60be278 100644
--- a/smp-angular/src/app/user/user-controller.ts
+++ b/smp-angular/src/app/user/user-controller.ts
@@ -1,6 +1,6 @@
 import {SearchTableController} from '../common/search-table/search-table-controller';
 import {MatDialog, MatDialogConfig, MatDialogRef} from '@angular/material';
-import {UserDetailsDialogComponent} from './user-details-dialog/user-details-dialog.component';
+import {UserDetailsDialogComponent, UserDetailsDialogMode} from './user-details-dialog/user-details-dialog.component';
 import {UserRo} from './user-ro.model';
 import {SearchTableEntityStatus} from '../common/search-table/search-table-entity-status.model';
 import {GlobalLookups} from "../common/global-lookups";
@@ -10,7 +10,6 @@ import {SmpConstants} from "../smp.constants";
 import {HttpClient} from "@angular/common/http";
 
 export class UserController implements SearchTableController {
-
   constructor(protected http: HttpClient, protected lookups: GlobalLookups, public dialog: MatDialog) { }
 
   public showDetails(row: any) {
@@ -22,12 +21,20 @@ export class UserController implements SearchTableController {
 
   public edit(row: any) { }
 
-  public delete(row: any) {
+  public delete(row: any) { }
 
+  public newDialog(config?: MatDialogConfig): MatDialogRef<UserDetailsDialogComponent> {
+    return this.dialog.open(UserDetailsDialogComponent, this.convertWithMode(config));
   }
 
-  public newDialog(config?: MatDialogConfig): MatDialogRef<UserDetailsDialogComponent> {
-    return this.dialog.open(UserDetailsDialogComponent, config);
+  private convertWithMode(config) {
+    return (config && config.data)
+      ? {...config,
+          data: {...config.data,
+            mode: config.data.mode || (config.data.edit ? UserDetailsDialogMode.EDIT_MODE : UserDetailsDialogMode.NEW_MODE)
+          }
+        }
+      : config;
   }
 
   public newRow(): UserRo {
@@ -43,7 +50,6 @@ export class UserController implements SearchTableController {
     }
   }
 
-
   public dataSaved() {
     this.lookups.refreshUserLookup();
   }
diff --git a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.html b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.html
index b031850b0d0d9a2182866df4611c041f0373e7ae..b22730bc83245c6f299c2d0103e7ec7743d46bd4 100644
--- a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.html
+++ b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.html
@@ -1,11 +1,10 @@
 <mat-dialog-content fxFlex="column">
-  <h2 mat-dialog-title>{{formTitle}}</h2>
+  <h2 mat-dialog-title>{{mode}}</h2>
 
   <mat-card>
     <mat-card-content >
-      <mat-slide-toggle class="user-toggle"
-                mat-no-ink class="mat-primary" [formControl]="userForm.controls['active']"
-                        (change)="onUserToggleChanged($event)" id="active_id">
+      <mat-slide-toggle *ngIf="!isPreferencesMode()" class="user-toggle"
+                mat-no-ink class="mat-primary" [formControl]="userForm.controls['active']" id="active_id">
         Active
       </mat-slide-toggle>
 
@@ -76,6 +75,9 @@
               - At least one digit<br>
               - At least one special character
             </div>
+            <div *ngIf="userForm.errors?.previousPasswordUsed" class="has-error">
+              Password should be different than the previous chosen one
+            </div>
           </mat-form-field>
 
           <mat-form-field class="password-confirmation">
diff --git a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts
index 64d0f45837c733fe84b134642fd60a3009566b52..ed852adbda5ada84b5ca0d832e2b852271f561d7 100644
--- a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts
+++ b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts
@@ -1,7 +1,7 @@
 import {Component, Inject, TemplateRef, ViewChild} from '@angular/core';
 import {MAT_DIALOG_DATA, MatDialogRef, MatSlideToggleChange} from '@angular/material';
 import {
-  AbstractControl,
+  AbstractControl, AsyncValidatorFn,
   FormBuilder,
   FormControl,
   FormGroup,
@@ -18,6 +18,9 @@ import {CertificateRo} from "../certificate-ro.model";
 import {DatePipe} from "../../custom-date/date.pipe";
 import {UserController} from "../user-controller";
 import {GlobalLookups} from "../../common/global-lookups";
+import {Observable, of} from "rxjs";
+import {catchError, map} from "rxjs/operators";
+import {UserDetailsService} from "./user-details.service";
 
 @Component({
   selector: 'user-details-dialog',
@@ -28,16 +31,14 @@ export class UserDetailsDialogComponent {
 
   @ViewChild('fileInput')  private fileInput;
 
-  static readonly NEW_MODE = 'New User';
-  static readonly EDIT_MODE = 'User Edit';
-
   readonly emailPattern = '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}';
   readonly passwordPattern = '^(?=.*[A-Z])(?=.*[ !#$%&\'()*+,-./:;<=>?@\\[^_`{|}~\\\]"])(?=.*[0-9])(?=.*[a-z]).{8,32}$';
   readonly dateFormat: string = 'yyyy-MM-dd HH:mm:ssZ';
   readonly usernamePattern='^[a-zA-Z0-9]{4,32}$';
 
+  mode: UserDetailsDialogMode;
   editMode: boolean;
-  formTitle: string;
+  userId: number;
   userRoles = [];
   existingRoles = [];
   userForm: FormGroup;
@@ -79,11 +80,31 @@ export class UserDetailsDialogComponent {
     &&  listIds.includes(certificateId.value) &&  this.current.certificate && certificateId.value !== this.current.certificate.certificateId ? { certificateIdExists: true} : null;
   };
 
+  private asyncPasswordValidator: AsyncValidatorFn = (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
+    if(this.isPreferencesMode()) {
+      const userToggle = control.get('userToggle');
+      const passwordToggle = control.get('passwordToggle');
+      const password = control.get('password');
+      const confirmation = control.get('confirmation');
+
+      if(userToggle && passwordToggle && password
+        && this.userId && userToggle.value && passwordToggle.value && password.value) {
+        return this.userDetailsService.isSamePreviousPasswordUsed$(this.userId, password.value).pipe(
+          map(previousPasswordUsed => previousPasswordUsed ? { previousPasswordUsed: true } : null),
+          catchError(() => {
+            this.alertService.error("Error occurred while validating the password against the previously chosen one!");
+            return of(null);
+          }));
+      }
+    }
+    return of(null);
+  };
+
   notInList(list: string[]) {
     return (c: AbstractControl): { [key: string]: any } => {
-      if (c.value && list.includes(c.value.toString().toLowerCase()))
+      if (c.value && list.includes(c.value.toString().toLowerCase())) {
         return {'notInList': {valid: false}};
-
+      }
       return null;
     }
   }
@@ -91,12 +112,14 @@ export class UserDetailsDialogComponent {
   constructor(private dialogRef: MatDialogRef<UserDetailsDialogComponent>,
               private lookups: GlobalLookups,
               private certificateService: CertificateService,
+              private userDetailsService: UserDetailsService,
               private alertService: AlertService,
               private datePipe: DatePipe,
               @Inject(MAT_DIALOG_DATA) public data: any,
               private fb: FormBuilder) {
-    this.editMode = data.edit;
-    this.formTitle = this.editMode ?  UserDetailsDialogComponent.EDIT_MODE: UserDetailsDialogComponent.NEW_MODE;
+    this.mode = data.mode;
+    this.userId = data.row && data.row.id;
+    this.editMode = this.mode !== UserDetailsDialogMode.NEW_MODE;
 
     this.current = this.editMode
       ? {
@@ -117,7 +140,7 @@ export class UserDetailsDialogComponent {
       };
 
     // The password authentication is if username exists
-    // if is off on clear than clear the username!
+    // if it's off on clear then clear the username!
     const bUserPasswordAuthentication: boolean = !!this.current.username;
     const bSetPassword: boolean = false;
 
@@ -129,14 +152,15 @@ export class UserDetailsDialogComponent {
       // common values
       'active': new FormControl({ value: ''},[]),
       'emailAddress': new FormControl({ value:'' },[ Validators.pattern(this.emailPattern), Validators.maxLength(255)]),
-      'role': new FormControl({ value: '' }, Validators.required),
+      'role': new FormControl({ value: '', disabled: this.mode === UserDetailsDialogMode.PREFERENCES_MODE }, Validators.required),
       // username/password authentication
       'userToggle': new FormControl(bUserPasswordAuthentication),
-      'passwordToggle': new FormControl({value: bSetPassword, disabled:!bUserPasswordAuthentication}),
+      'passwordToggle': new FormControl({value: bSetPassword, disabled: !bUserPasswordAuthentication}),
       'username': new FormControl({ value: '', disabled: this.editMode || !bUserPasswordAuthentication },
-        !this.editMode || !this.current.username ? [Validators.nullValidator, Validators.pattern(this.usernamePattern),
-          this.notInList(this.lookups.cachedServiceGroupOwnerList.map(a => a.username?a.username.toLowerCase():null))] : null),
-      //       // improve notInList validator
+        !this.editMode || !this.current.username
+          ? [Validators.nullValidator, Validators.pattern(this.usernamePattern), this.notInList(this.lookups.cachedServiceGroupOwnerList.map(a => a.username ? a.username.toLowerCase() : null))]
+          : null),
+      // improve notInList validator
       'password': new FormControl({ value: '', disabled: !bUserPasswordAuthentication || !bSetPassword},
         [Validators.required, Validators.pattern(this.passwordPattern)]),
       'confirmation': new FormControl({ value: '', disabled: !bUserPasswordAuthentication  || !bSetPassword},
@@ -155,7 +179,8 @@ export class UserDetailsDialogComponent {
         this.atLeastOneToggleCheckedValidator,
         this.certificateValidator,
         this.certificateExistValidator,
-        ]
+        ],
+      asyncValidator: this.asyncPasswordValidator,
     });
     // bind values to form! not property
     this.userForm.controls['active'].setValue(this.current.active);
@@ -172,9 +197,9 @@ export class UserDetailsDialogComponent {
     this.userForm.controls['serialNumber'].setValue(this.current.certificate.serialNumber);
     this.userForm.controls['certificateId'].setValue(this.current.certificate.certificateId);
 
-    // if edit mode and user is given - toggle is dissabled
-    // username should  not be changed.!
-    if (this.editMode  && !!this.current.username){
+    // if edit mode and user is given - toggle is disabled
+    // username should not be changed.!
+    if (this.editMode && bUserPasswordAuthentication){
       this.userForm.controls['userToggle'].disable();
     }
   }
@@ -215,7 +240,6 @@ export class UserDetailsDialogComponent {
   }
 
   onCertificateToggleChanged({checked}: MatSlideToggleChange) {
-
     if (checked) {
       // fill from temp
       this.userForm.controls['certificateId'].setValue( this.tempStoreForCertificate.certificateId);
@@ -241,7 +265,6 @@ export class UserDetailsDialogComponent {
       this.userForm.controls['validFrom'].setValue("");
       this.userForm.controls['validTo'].setValue("");
     }
-
   }
 
   onUserToggleChanged({checked}: MatSlideToggleChange) {
@@ -258,7 +281,6 @@ export class UserDetailsDialogComponent {
       this.tempStoreForUser.username =  this.userForm.controls['username'].value;
       this.tempStoreForUser.password =  this.userForm.controls['password'].value;
 
-
       this.userForm.controls['username'].setValue("");
       this.userForm.controls['password'].setValue("");
     }
@@ -275,6 +297,10 @@ export class UserDetailsDialogComponent {
     }
   }
 
+  isPreferencesMode() {
+    return this.mode === UserDetailsDialogMode.PREFERENCES_MODE;
+  }
+
   public getCurrent(): UserRo {
     this.current.active =this.userForm.get('active').value;
     this.current.emailAddress =this.userForm.get('emailAddress').value;
@@ -346,3 +372,9 @@ export class UserDetailsDialogComponent {
     }
   }
 }
+
+export enum UserDetailsDialogMode {
+  NEW_MODE = 'New User',
+  EDIT_MODE = 'User Edit',
+  PREFERENCES_MODE = 'Edit',
+}
diff --git a/smp-angular/src/app/user/user-details-dialog/user-details.service.ts b/smp-angular/src/app/user/user-details-dialog/user-details.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..221b7011ac05a5191105617802e82657559b7600
--- /dev/null
+++ b/smp-angular/src/app/user/user-details-dialog/user-details.service.ts
@@ -0,0 +1,17 @@
+import {Injectable} from "@angular/core";
+import {HttpClient} from "@angular/common/http";
+import {catchError, map} from "rxjs/operators";
+import {SmpConstants} from "../../smp.constants";
+import {Observable} from "rxjs";
+
+@Injectable()
+export class UserDetailsService {
+
+  constructor(
+    private http: HttpClient,
+  ) { }
+
+  isSamePreviousPasswordUsed$(userId: number, password: string): Observable<boolean> {
+    return this.http.post<boolean>(`${SmpConstants.REST_USER}/${userId}/samePreviousPasswordUsed`, password);
+  }
+}
diff --git a/smp-angular/src/app/user/user.service.ts b/smp-angular/src/app/user/user.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4a9a31236d374d2d5e0b33b173babb24191b0604
--- /dev/null
+++ b/smp-angular/src/app/user/user.service.ts
@@ -0,0 +1,27 @@
+import {Injectable} from '@angular/core';
+import {Observable, of, Subject} from 'rxjs';
+import {HttpClient} from '@angular/common/http';
+import {Role} from '../security/role.model';
+import {SmpConstants} from "../smp.constants";
+import {User} from "../security/user.model";
+import {AlertService} from "../alert/alert.service";
+import {SecurityService} from "../security/security.service";
+
+@Injectable()
+export class UserService {
+
+  constructor(
+    private http: HttpClient,
+    private securityService: SecurityService,
+    private alertService: AlertService,
+  ) { }
+
+  updateUser(user: User) {
+    this.http.put<string>(`${SmpConstants.REST_USER}/${user.id}`, user).subscribe(response => {
+      this.securityService.updateUserDetails(response);
+      this.alertService.success('The operation \'update user\' completed successfully.');
+    }, err => {
+      this.alertService.exception('The operation \'update user\' not completed successfully.', err);
+    });
+  }
+}
diff --git a/smp-server-library/pom.xml b/smp-server-library/pom.xml
index cdc609be8ae8c0dbac413eeea5a226b25a3b5bec..7034665ad29c15f199f514d2f9a90cad33804368 100644
--- a/smp-server-library/pom.xml
+++ b/smp-server-library/pom.xml
@@ -218,6 +218,7 @@
                 <filtering>true</filtering>
                 <excludes>
                     <exclude>**/*.jks</exclude>
+                    <exclude>**/*.crt</exclude>
                 </excludes>
             </testResource>
             <testResource>
@@ -226,6 +227,7 @@
                 <!-- With filtering=true Maven was introducing changes in keystore binary files [sic!] -->
                 <includes>
                     <include>**/*.jks</include>
+                    <include>**/*.crt</include>
                 </includes>
             </testResource>
         </testResources>
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/CertificateROToDBCertificateConverter.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/CertificateROToDBCertificateConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b1c4113e7bed99fda369e0228ee12c5e266d182
--- /dev/null
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/CertificateROToDBCertificateConverter.java
@@ -0,0 +1,32 @@
+package eu.europa.ec.edelivery.smp.conversion;
+
+import eu.europa.ec.edelivery.smp.data.model.DBCertificate;
+import eu.europa.ec.edelivery.smp.data.ui.CertificateRO;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+
+/**
+ * @author Sebastian-Ion TINCU
+ */
+@Component
+public class CertificateROToDBCertificateConverter implements Converter<CertificateRO, DBCertificate> {
+
+    @Override
+    public DBCertificate convert(CertificateRO source) {
+        DBCertificate target = new DBCertificate();
+        if (source.getValidTo() != null) {
+            target.setValidTo(LocalDateTime.ofInstant(source.getValidTo().toInstant(), ZoneId.systemDefault()));
+        }
+        if (source.getValidFrom() != null) {
+            target.setValidFrom(LocalDateTime.ofInstant(source.getValidFrom().toInstant(), ZoneId.systemDefault()));
+        }
+        target.setCertificateId(source.getCertificateId());
+        target.setSerialNumber(source.getSerialNumber());
+        target.setIssuer(source.getIssuer());
+        target.setSubject(source.getSubject());
+        return target;
+    }
+}
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/ConvertersRegistrar.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/ConvertersRegistrar.java
new file mode 100644
index 0000000000000000000000000000000000000000..8669adc2844029c7814dcbeb1cfbd9f8060b23ac
--- /dev/null
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/ConvertersRegistrar.java
@@ -0,0 +1,35 @@
+package eu.europa.ec.edelivery.smp.conversion;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.core.convert.support.ConfigurableConversionService;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * Registrar allowing registration of custom {@link org.springframework.core.convert.converter.Converter converters} for
+ * the back-end domain model and autowiring them with the {@link org.springframework.core.convert.ConversionService} and
+ * possibly other Spring beans (by first autowiring them into this registrar).
+ *
+ * @author Sebastian-Ion TINCU
+ */
+@Component
+public class ConvertersRegistrar {
+
+    private final Logger logger = LoggerFactory.getLogger(ConvertersRegistrar.class);
+
+    @Autowired
+    private ConfigurableConversionService conversionRegistry;
+
+    @Autowired
+    public void registerCustomConverters(List<Converter<?,?>> converters) {
+        for (Converter<?, ?> converter : converters) {
+            conversionRegistry.addConverter(converter);
+        }
+
+        logger.info("Finished registering custom converters: {}", converters);
+    }
+}
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/DBCertificateToCertificateROConverter.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/DBCertificateToCertificateROConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7e55effe436db6532412916a374553731465ba6
--- /dev/null
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/DBCertificateToCertificateROConverter.java
@@ -0,0 +1,32 @@
+package eu.europa.ec.edelivery.smp.conversion;
+
+import eu.europa.ec.edelivery.smp.data.model.DBCertificate;
+import eu.europa.ec.edelivery.smp.data.ui.CertificateRO;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+import java.sql.Date;
+import java.time.ZoneOffset;
+
+/**
+ * @author Sebastian-Ion TINCU
+ */
+@Component
+public class DBCertificateToCertificateROConverter implements Converter<DBCertificate, CertificateRO> {
+
+    @Override
+    public CertificateRO convert(DBCertificate source) {
+        CertificateRO target = new CertificateRO();
+        if (source.getValidTo() != null) {
+            target.setValidTo(Date.from(source.getValidTo().toInstant(ZoneOffset.UTC)));
+        }
+        if (source.getValidFrom() != null) {
+            target.setValidFrom(Date.from(source.getValidFrom().toInstant(ZoneOffset.UTC)));
+        }
+        target.setCertificateId(source.getCertificateId());
+        target.setSerialNumber(source.getSerialNumber());
+        target.setIssuer(source.getIssuer());
+        target.setSubject(source.getSubject());
+        return target;
+    }
+}
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/DBUserToUserROConverter.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/DBUserToUserROConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..e3d69649b0edfae28847e8fd0bae4eb4c2782d06
--- /dev/null
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/DBUserToUserROConverter.java
@@ -0,0 +1,36 @@
+package eu.europa.ec.edelivery.smp.conversion;
+
+import eu.europa.ec.edelivery.smp.data.model.DBUser;
+import eu.europa.ec.edelivery.smp.data.ui.CertificateRO;
+import eu.europa.ec.edelivery.smp.data.ui.UserRO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.convert.ConversionService;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Sebastian-Ion TINCU
+ */
+@Component
+public class DBUserToUserROConverter implements Converter<DBUser, UserRO> {
+
+    @Autowired
+    private ConversionService conversionService;
+
+    @Override
+    public UserRO convert(DBUser source) {
+        UserRO target = new UserRO();
+        target.setEmailAddress(source.getEmailAddress());
+        target.setUsername(source.getUsername());
+        target.setRole(source.getRole());
+        target.setPassword(source.getPassword());
+        target.setPasswordChanged(source.getPasswordChanged());
+        target.setActive(source.isActive());
+        target.setId(source.getId());
+        if (source.getCertificate() != null) {
+            CertificateRO certificateRO = conversionService.convert(source.getCertificate(), CertificateRO.class);
+            target.setCertificate(certificateRO);
+        }
+        return target;
+    }
+}
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/UserROToDBUserConverter.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/UserROToDBUserConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..7dc34f62a75a8b363ccb30a5389e0183fb64e1bf
--- /dev/null
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/UserROToDBUserConverter.java
@@ -0,0 +1,36 @@
+package eu.europa.ec.edelivery.smp.conversion;
+
+import eu.europa.ec.edelivery.smp.data.model.DBCertificate;
+import eu.europa.ec.edelivery.smp.data.model.DBUser;
+import eu.europa.ec.edelivery.smp.data.ui.UserRO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.convert.ConversionService;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Sebastian-Ion TINCU
+ */
+@Component
+public class UserROToDBUserConverter implements Converter<UserRO, DBUser> {
+
+    @Autowired
+    private ConversionService conversionService;
+
+    @Override
+    public DBUser convert(UserRO source) {
+        DBUser dro = new DBUser();
+        dro.setEmailAddress(source.getEmailAddress());
+        dro.setUsername(source.getUsername());
+        dro.setRole(source.getRole());
+        dro.setPassword(source.getPassword());
+        dro.setActive(source.isActive());
+        dro.setId(source.getId());
+        dro.setPasswordChanged(source.getPasswordChanged());
+        if (source.getCertificate() != null) {
+            DBCertificate certData = conversionService.convert(source.getCertificate(), DBCertificate.class);
+            dro.setCertificate(certData);
+        }
+        return dro;
+    }
+}
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/UserDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/UserDao.java
index e4d8e98ba64c1cd7f69990a87e8ad2a2fd6e7900..49e0b2860da5cd7f19da8a99b9dfcf31e4e8a027 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/UserDao.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/UserDao.java
@@ -36,10 +36,8 @@ import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.ILLEGAL_STATE_USER
 @Repository
 public class UserDao extends BaseDao<DBUser> {
 
-
-
     /**
-     * Persis user to database. Before that test if user has identifiers. Usernames are saved to database in lower caps
+     * Persists the user to the database. Before that test if user has identifiers. Usernames are saved to database in lower caps
      * @param user
      */
     @Override
@@ -57,7 +55,18 @@ public class UserDao extends BaseDao<DBUser> {
     }
 
     /**
-     * Method finds user by identifier. User identifier is username or certificateId. First it tries to find user by username
+     * Searches for a user entity by its primary key and returns it if found. Returns an empty {@code Optional} if missing.
+     *
+     * @param userId The primary key of the user entity to find
+     * @return an optional user entity
+     */
+    public Optional<DBUser> findUser(Long userId) {
+        DBUser dbUser = memEManager.find(DBUser.class, userId);
+        return Optional.ofNullable(dbUser);
+    }
+
+    /**
+     * Finds a user by identifier. User identifier is username or certificateId. First it tries to find user by username
      * and than by certificate id. If user does not exists Optional with isPresent - false is returned.
      * @param identifier
      * @return resturns Optional DBUser for identifier
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java
index 4b52c4f3a0e8e51ea40b9203ddd2c455f814907f..d47773cb2914d5d5639cdb0ef32d10d369e47774 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java
@@ -12,14 +12,15 @@ import eu.europa.ec.edelivery.smp.data.ui.DeleteEntityValidation;
 import eu.europa.ec.edelivery.smp.data.ui.ServiceResult;
 import eu.europa.ec.edelivery.smp.data.ui.UserRO;
 import eu.europa.ec.edelivery.smp.data.ui.enums.EntityROStatus;
+import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
+import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.crypto.bcrypt.BCrypt;
+import org.springframework.core.convert.ConversionService;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import sun.java2d.pipe.SpanShapeRenderer;
 
 import java.io.*;
 import java.math.BigInteger;
@@ -27,11 +28,9 @@ import java.net.URLEncoder;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
-import java.sql.Date;
 import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
-import java.time.ZoneOffset;
 import java.util.Arrays;
 import java.util.Base64;
 import java.util.List;
@@ -42,12 +41,16 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(UIUserService.class);
 
     private static final byte[] S_PEM_START_TAG = "-----BEGIN CERTIFICATE-----\n".getBytes();
+
     private static final byte[] S_PEM_END_TAG = "\n-----END CERTIFICATE-----".getBytes();
 
     private static final String S_BLUECOAT_DATEFORMAT ="MMM dd HH:mm:ss yyyy";
 
     @Autowired
-    UserDao userDao;
+    private UserDao userDao;
+
+    @Autowired
+    private ConversionService conversionService;
 
     @Override
     protected BaseDao<DBUser> getDatabaseDao() {
@@ -62,13 +65,10 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
      * @param sortField
      * @param sortOrder
      * @param filter
-     * @return ServiceResult wiht list
+     * @return ServiceResult with list
      */
     @Transactional
-    public ServiceResult<UserRO> getTableList(int page, int pageSize,
-                                              String sortField,
-                                              String sortOrder, Object filter) {
-
+    public ServiceResult<UserRO> getTableList(int page, int pageSize, String sortField, String sortOrder, Object filter) {
         ServiceResult<UserRO> resUsers = super.getTableList(page, pageSize, sortField, sortOrder, filter);
         resUsers.getServiceEntities().forEach(usr -> usr.setPassword(null));
         return resUsers;
@@ -78,7 +78,6 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
     public void updateUserList(List<UserRO> lst) {
         boolean suc = false;
         for (UserRO userRO : lst) {
-
             if (userRO.getStatus() == EntityROStatus.NEW.getStatusNumber()) {
                 DBUser dbUser = convertFromRo(userRO);
                 if (!StringUtils.isBlank(userRO.getPassword())) {
@@ -125,8 +124,19 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
         }
     }
 
-    public CertificateRO getCertificateData(byte[] buff) throws CertificateException, IOException {
+    /**
+     * Returns the user entity by its primary key or throws a {@code SMPRuntimeException} if such entity does not exist.
+     *
+     * @param userId The primary key of the user entity
+     * @return the user entity
+     * @throws SMPRuntimeException if a user entity having the provided primary key does not exist.
+     */
+    @Transactional(readOnly = true)
+    public DBUser findUser(Long userId) {
+        return userDao.findUser(userId).orElseThrow(() -> new SMPRuntimeException(ErrorCode.USER_NOT_EXISTS));
+    }
 
+    public CertificateRO getCertificateData(byte[] buff) throws CertificateException, IOException {
         // get pem encoding -
         InputStream isCert = createPEMFormat(buff);
 
@@ -227,9 +237,6 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
             return null;
         }
         return Arrays.copyOfRange(buff, iStart, iEnd + S_PEM_END_TAG.length);
-
-
-
     }
 
     /**
@@ -258,32 +265,7 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
 
     @Override
     public UserRO convertToRo(DBUser d) {
-
-        UserRO dro = new UserRO();
-        dro.setEmailAddress(d.getEmailAddress());
-        dro.setUsername(d.getUsername());
-        dro.setRole(d.getRole());
-        dro.setPassword(d.getPassword());
-        dro.setPasswordChanged(d.getPasswordChanged());
-        dro.setActive(d.isActive());
-        dro.setId(d.getId());
-
-        if (d.getCertificate() != null) {
-            CertificateRO certData = new CertificateRO();
-            if (d.getCertificate().getValidTo() != null) {
-
-                certData.setValidTo(Date.from(d.getCertificate().getValidTo().toInstant(ZoneOffset.UTC)));
-            }
-            if (d.getCertificate().getValidFrom() != null) {
-                certData.setValidFrom(Date.from(d.getCertificate().getValidFrom().toInstant(ZoneOffset.UTC)));
-            }
-            certData.setCertificateId(d.getCertificate().getCertificateId());
-            certData.setSerialNumber(d.getCertificate().getSerialNumber());
-            certData.setIssuer(d.getCertificate().getIssuer());
-            certData.setSubject(d.getCertificate().getSubject());
-            dro.setCertificate(certData);
-        }
-        return dro;
+        return conversionService.convert(d, UserRO.class);
     }
 
     public DeleteEntityValidation validateDeleteRequest(DeleteEntityValidation dev){
@@ -306,31 +288,6 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
 
     @Override
     public DBUser convertFromRo(UserRO d) {
-        DBUser dro = new DBUser();
-        dro.setEmailAddress(d.getEmailAddress());
-        dro.setUsername(d.getUsername());
-        dro.setRole(d.getRole());
-        dro.setPassword(d.getPassword());
-        dro.setActive(d.isActive());
-        dro.setId(d.getId());
-        dro.setPasswordChanged(d.getPasswordChanged());
-        if (d.getCertificate() != null) {
-            DBCertificate certData = new DBCertificate();
-            if (d.getCertificate().getValidTo() != null) {
-                certData.setValidTo(LocalDateTime.ofInstant(d.getCertificate().getValidTo().toInstant(), ZoneId.systemDefault()));
-            }
-            if (d.getCertificate().getValidFrom() != null) {
-                certData.setValidFrom(LocalDateTime.ofInstant(d.getCertificate().getValidFrom().toInstant(), ZoneId.systemDefault()));
-            }
-            certData.setCertificateId(d.getCertificate().getCertificateId());
-            certData.setSerialNumber(d.getCertificate().getSerialNumber());
-            certData.setIssuer(d.getCertificate().getIssuer());
-            certData.setSubject(d.getCertificate().getSubject());
-
-            dro.setCertificate(certData);
-        }
-        return dro;
-
+        return conversionService.convert(d, DBUser.class);
     }
-
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/ConversionTestConfig.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/ConversionTestConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..d523cc6dba4c3e496050035196fbb81937236a68
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/ConversionTestConfig.java
@@ -0,0 +1,19 @@
+package eu.europa.ec.edelivery.smp.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.support.ConversionServiceFactoryBean;
+
+/**
+ * @author Sebastian-Ion TINCU
+ */
+@Configuration
+@ComponentScan("eu.europa.ec.edelivery.smp.conversion")
+public class ConversionTestConfig {
+
+    @Bean
+    public ConversionServiceFactoryBean conversionService() {
+        return new ConversionServiceFactoryBean();
+    }
+}
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/H2JPATestConfiguration.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/H2JPATestConfig.java
similarity index 98%
rename from smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/H2JPATestConfiguration.java
rename to smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/H2JPATestConfig.java
index 62492632775a4a64da5abbf2c68cfdf6fd20a69d..bf1c76de708183de560f798218e8b27422b923bd 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/H2JPATestConfiguration.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/H2JPATestConfig.java
@@ -1,6 +1,5 @@
 package eu.europa.ec.edelivery.smp.config;
 
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -22,7 +21,8 @@ import java.sql.SQLException;
 @Configuration
 @PropertySource("./persistence-test-h2.properties")
 @EnableTransactionManagement
-public class H2JPATestConfiguration {
+public class H2JPATestConfig {
+
     @Autowired
     private Environment env;
 
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AbstractBaseDao.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AbstractBaseDao.java
index 538f03dcbcf1157250f9182a299c266f70a615a4..a5e3e4c09a6cd5103ecb63c83058d0af77c870aa 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AbstractBaseDao.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AbstractBaseDao.java
@@ -1,16 +1,14 @@
 package eu.europa.ec.edelivery.smp.data.dao;
 
-
-import eu.europa.ec.edelivery.smp.config.H2JPATestConfiguration;
+import eu.europa.ec.edelivery.smp.config.H2JPATestConfig;
 import org.junit.runner.RunWith;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.jdbc.Sql;
 import org.springframework.test.context.jdbc.SqlConfig;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-
 @RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = {H2JPATestConfiguration.class,
+@ContextConfiguration(classes = {H2JPATestConfig.class,
         ServiceGroupDao.class, ServiceMetadataDao.class, DomainDao.class, UserDao.class})
 @Sql(scripts = "classpath:cleanup-database.sql",
         executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig
@@ -19,5 +17,4 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
                 dataSource = "h2DataSource"))
 public abstract class AbstractBaseDao {
 
-
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AuditIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AuditIntegrationTest.java
index a6778b6f1ae02b4f97fe8db2632761b28f4e88b1..653dd60bfe9f0129b583fb45b122760f93df5cab 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AuditIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AuditIntegrationTest.java
@@ -10,10 +10,9 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the Licence for the specific language governing permissions and limitations under the Licence.
  */
-
 package eu.europa.ec.edelivery.smp.data.dao;
 
-import eu.europa.ec.edelivery.smp.config.H2JPATestConfiguration;
+import eu.europa.ec.edelivery.smp.config.H2JPATestConfig;
 import eu.europa.ec.edelivery.smp.data.model.*;
 import org.hibernate.envers.AuditReader;
 import org.hibernate.envers.AuditReaderFactory;
@@ -36,7 +35,6 @@ import java.util.UUID;
 import static eu.europa.ec.edelivery.smp.testutil.TestDBUtils.createDBDomain;
 import static org.junit.Assert.assertTrue;
 
-
 /**
  *  Purpose of class is to test all Audit classes and  methods with database.
  *
@@ -44,7 +42,7 @@ import static org.junit.Assert.assertTrue;
  * @since 4.1
  */
 @RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = {H2JPATestConfiguration.class})
+@ContextConfiguration(classes = {H2JPATestConfig.class})
 @Sql(scripts = "classpath:cleanup-database.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig
         (transactionMode = SqlConfig.TransactionMode.ISOLATED,
                 transactionManager = "transactionManager",
@@ -56,8 +54,6 @@ public class AuditIntegrationTest {
     @PersistenceUnit
     EntityManagerFactory emf;
 
-
-
     @Test
     public void testClassesForAudit() {
         AuditReader ar = AuditReaderFactory.get(emf.createEntityManager());
@@ -69,7 +65,6 @@ public class AuditIntegrationTest {
         assertTrue(ar.isEntityClassAudited(DBServiceGroupExtension.class));
     }
 
-
     @Test
     public void testAuditDBDomain() {
 
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/DomainDaoIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/DomainDaoIntegrationTest.java
index ce7f681c4c083b12124eacd18839161f5567df2a..a58e342bd42b1ca574b2682275db9a09f7a9afba 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/DomainDaoIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/DomainDaoIntegrationTest.java
@@ -1,6 +1,5 @@
 package eu.europa.ec.edelivery.smp.data.dao;
 
-import eu.europa.ec.edelivery.smp.config.H2JPATestConfiguration;
 import eu.europa.ec.edelivery.smp.data.model.*;
 import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
 import eu.europa.ec.edelivery.smp.testutil.TestConstants;
@@ -8,12 +7,7 @@ import eu.europa.ec.edelivery.smp.testutil.TestDBUtils;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.jdbc.Sql;
-import org.springframework.test.context.jdbc.SqlConfig;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
 import java.util.Collections;
 import java.util.List;
@@ -38,7 +32,6 @@ public class DomainDaoIntegrationTest extends AbstractBaseDao {
     @Rule
     public ExpectedException expectedEx = ExpectedException.none();
 
-
     @Test
     public void persistDomain() {
         // set
@@ -93,7 +86,6 @@ public class DomainDaoIntegrationTest extends AbstractBaseDao {
         assertTrue(!res.isPresent());
     }
 
-
     @Test
     public void getDomainByCodeExists() {
         // set
@@ -162,7 +154,6 @@ public class DomainDaoIntegrationTest extends AbstractBaseDao {
         assertFalse(optDmn.isPresent());
     }
 
-
     @Test
     public void testValidateUsersForDeleteOKScenario() {
         // set
@@ -185,7 +176,6 @@ public class DomainDaoIntegrationTest extends AbstractBaseDao {
 
         serviceGroupDao.persistFlushDetach(sg);
 
-
         // execute
         List<DBDomainDeleteValidation> lst = testInstance.validateDomainsForDelete(Collections.singletonList(d.getId()));
         assertEquals(1, lst.size());
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ServiceGroupDaoIntegrationBase.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ServiceGroupDaoIntegrationBase.java
index f6da7769f20d8b1d7bedc07b44808334bc835c38..3dfa1a99a79a83abf22afcf3a9b3ecbdb6b1b7a1 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ServiceGroupDaoIntegrationBase.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ServiceGroupDaoIntegrationBase.java
@@ -1,6 +1,5 @@
 package eu.europa.ec.edelivery.smp.data.dao;
 
-import eu.europa.ec.edelivery.smp.config.H2JPATestConfiguration;
 import eu.europa.ec.edelivery.smp.data.model.DBDomain;
 import eu.europa.ec.edelivery.smp.data.model.DBServiceGroup;
 import eu.europa.ec.edelivery.smp.data.model.DBServiceMetadata;
@@ -11,15 +10,11 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.rules.ExpectedException;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.jdbc.Sql;
-import org.springframework.test.context.jdbc.SqlConfig;
 
 import javax.transaction.Transactional;
 
 import static eu.europa.ec.edelivery.smp.testutil.TestConstants.*;
 
-
 /**
  * Purpose of class is to test all resource methods with database.
  *
@@ -55,7 +50,6 @@ public abstract class ServiceGroupDaoIntegrationBase extends AbstractBaseDao{
         userDao.persistFlushDetach(u3);
     }
 
-
    public DBServiceGroup createAndSaveNewServiceGroup(){
        return createAndSaveNewServiceGroup(TEST_DOMAIN_CODE_1, TestConstants.TEST_SG_ID_1, TestConstants.TEST_SG_SCHEMA_1);
    }
@@ -75,7 +69,6 @@ public abstract class ServiceGroupDaoIntegrationBase extends AbstractBaseDao{
        return sg;
    }
 
-
     public void createAndSaveNewServiceGroups(int iCount, String domain, String participant){
         createAndSaveNewServiceGroups(iCount, domain, participant, null);
     }
@@ -119,5 +112,4 @@ public abstract class ServiceGroupDaoIntegrationBase extends AbstractBaseDao{
         testInstance.update(sg);
     }
 
-
 }
\ No newline at end of file
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ServiceMetadataDaoIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ServiceMetadataDaoIntegrationTest.java
index 8ef4e1198fb7f5a880e51d50f8b2333f18e9e1c1..1a81d1cba1cd0cfcceaffc3e5edeb559891e31ac 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ServiceMetadataDaoIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ServiceMetadataDaoIntegrationTest.java
@@ -1,6 +1,5 @@
 package eu.europa.ec.edelivery.smp.data.dao;
 
-import eu.europa.ec.edelivery.smp.config.H2JPATestConfiguration;
 import eu.europa.ec.edelivery.smp.data.model.DBDomain;
 import eu.europa.ec.edelivery.smp.data.model.DBServiceGroup;
 import eu.europa.ec.edelivery.smp.data.model.DBServiceMetadata;
@@ -11,12 +10,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.jdbc.Sql;
-import org.springframework.test.context.jdbc.SqlConfig;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
 import javax.transaction.Transactional;
 import java.util.List;
@@ -116,5 +110,4 @@ public class ServiceMetadataDaoIntegrationTest extends AbstractBaseDao {
         assertEquals(2, lst2.size());
     }
 
-
 }
\ No newline at end of file
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AbstractServiceIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AbstractServiceIntegrationTest.java
index 1aacf70e34257531d47268887fa9906ce6c24b54..8ad02e5c2a8f7b4b6140fd4a9723c74f13781cbc 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AbstractServiceIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AbstractServiceIntegrationTest.java
@@ -1,7 +1,7 @@
 package eu.europa.ec.edelivery.smp.services;
 
 
-import eu.europa.ec.edelivery.smp.config.H2JPATestConfiguration;
+import eu.europa.ec.edelivery.smp.config.H2JPATestConfig;
 import eu.europa.ec.edelivery.smp.config.PropertiesSingleDomainTestConfig;
 import eu.europa.ec.edelivery.smp.conversion.CaseSensitivityNormalizer;
 import eu.europa.ec.edelivery.smp.data.dao.DomainDao;
@@ -33,7 +33,7 @@ import static eu.europa.ec.edelivery.smp.testutil.TestConstants.*;
  */
 
 @RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = {H2JPATestConfiguration.class,PropertiesSingleDomainTestConfig.class,
+@ContextConfiguration(classes = {H2JPATestConfig.class,PropertiesSingleDomainTestConfig.class,
         CaseSensitivityNormalizer.class,SmlConnector.class,ServiceMetadataSigner.class,
         ServiceGroupService.class, DomainService.class, ServiceMetadataService.class,
         ServiceGroupDao.class,ServiceMetadataDao.class, DomainDao.class, UserDao.class,DBAssertion.class})
@@ -175,5 +175,4 @@ public abstract class AbstractServiceIntegrationTest {
         sg3.getServiceGroupDomains().get(1).addServiceMetadata(sg3md2);
         serviceGroupDao.update(sg3);
     }
-
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java
index a261fdc55c9af6f6ac8031f2ca2bfa91b82806f1..6791adeb22bcc134d46bfec931d5e7198ea80d60 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java
@@ -1,6 +1,7 @@
 package eu.europa.ec.edelivery.smp.services.ui;
 
 
+import eu.europa.ec.edelivery.smp.config.ConversionTestConfig;
 import eu.europa.ec.edelivery.smp.data.model.DBCertificate;
 import eu.europa.ec.edelivery.smp.data.model.DBUser;
 import eu.europa.ec.edelivery.smp.data.ui.CertificateRO;
@@ -17,14 +18,21 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.crypto.bcrypt.BCrypt;
 import org.springframework.test.context.ContextConfiguration;
 
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.security.cert.CertificateException;
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
-import java.util.*;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Optional;
+import java.util.UUID;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 
 /**
@@ -33,7 +41,7 @@ import static org.junit.Assert.*;
  * @author Joze Rihtarsic
  * @since 4.1
  */
-@ContextConfiguration(classes= UIUserService.class)
+@ContextConfiguration(classes = {UIUserService.class, ConversionTestConfig.class})
 public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest {
     @Rule
     public ExpectedException expectedExeption = ExpectedException.none();
@@ -51,11 +59,11 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
 
     @Test
     public void testGetTableListEmpty() {
-
         // given
 
         //when
         ServiceResult<UserRO> res = testInstance.getTableList(-1, -1, null, null, null);
+
         // then
         assertNotNull(res);
         assertEquals(0, res.getCount().intValue());
@@ -67,9 +75,9 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
 
     @Test
     public void testGetTableList15() {
-
         // given
         insertDataObjects(15);
+
         //when
         ServiceResult<UserRO> res = testInstance.getTableList(-1, -1, null, null, null);
 
@@ -127,6 +135,7 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
 
         //when
         testInstance.updateUserList(Collections.singletonList(user));
+
         // then
         long  iCntNew  = userDao.getDataListCount(null);
         assertEquals(iCnt+1, iCntNew);
@@ -166,9 +175,9 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
 
         user.setStatus(EntityROStatus.NEW.getStatusNumber());
 
-
         //when
         testInstance.updateUserList(Collections.singletonList(user));
+
         // then
         long  iCntNew  = userDao.getDataListCount(null);
         assertEquals(iCnt+1, iCntNew);
@@ -212,9 +221,9 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
 
         user.setStatus(EntityROStatus.NEW.getStatusNumber());
 
-
         //when
         testInstance.updateUserList(Collections.singletonList(user));
+
         // then
         long  iCntNew  = userDao.getDataListCount(null);
         assertEquals(iCnt+1, iCntNew);
@@ -262,6 +271,7 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
         userRO.setStatus(EntityROStatus.UPDATED.getStatusNumber());
 
         testInstance.updateUserList(Collections.singletonList(userRO));
+
         // then
         ServiceResult<UserRO> res  =  testInstance.getTableList(-1,-1,null, null, null);
         assertEquals(1, urTest.getServiceEntities().size());
@@ -296,8 +306,10 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
     public void testGetCertificateDataPEM() throws IOException, CertificateException {
         // given
         byte[] buff = IOUtils.toByteArray(UIUserServiceIntegrationTest.class.getResourceAsStream("/truststore/SMPtest.crt"));
+
         // when
         CertificateRO cer = testInstance.getCertificateData(buff);
+
         //then
         assertEquals("CN=SMP test,O=DIGIT,C=BE:0000000000000003", cer.getCertificateId());
         assertEquals("CN=Intermediate CA, O=DIGIT, C=BE", cer.getIssuer());
@@ -312,8 +324,10 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
     public void testGetCertificateDataPEMWithHeader() throws IOException, CertificateException {
         // given
         byte[] buff = IOUtils.toByteArray(UIUserServiceIntegrationTest.class.getResourceAsStream("/truststore/pem-with-header.crt"));
+
         // when
         CertificateRO cer = testInstance.getCertificateData(buff);
+
         //then
         assertEquals("CN=alice,O=www.freelan.org,C=FR:0000000000000001", cer.getCertificateId());
         assertEquals("EMAILADDRESS=contact@freelan.org, CN=Freelan Sample Certificate Authority, OU=freelan, O=www.freelan.org, L=Strasbourg, ST=Alsace, C=FR", cer.getIssuer());
@@ -324,15 +338,14 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
         assertTrue(cer.getValidFrom().before(cer.getValidTo()));
     }
 
-
-
     @Test
     public void testGetCertificateDataDER() throws IOException, CertificateException {
         // given
-        byte[] buff = IOUtils.toByteArray(new FileInputStream("src/test/resources/truststore/NewPeppolAP.crt"));
+        byte[] buff = IOUtils.toByteArray(UIUserServiceIntegrationTest.class.getResourceAsStream("/truststore/NewPeppolAP.crt"));
 
         // when
         CertificateRO cer = testInstance.getCertificateData(buff);
+
         //then
         assertEquals("CN=POP000004,O=European Commission,C=BE:474980c51478cf62761667461aef5e8e", cer.getCertificateId());
         assertEquals("CN=PEPPOL ACCESS POINT TEST CA - G2, OU=FOR TEST ONLY, O=OpenPEPPOL AISBL, C=BE", cer.getIssuer());
@@ -342,5 +355,4 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
         assertNotNull(cer.getValidTo());
         assertTrue(cer.getValidFrom().before(cer.getValidTo()));
     }
-
 }
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationService.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationService.java
new file mode 100644
index 0000000000000000000000000000000000000000..923c635c570c34e90b2265b9c70c7eada37ffedf
--- /dev/null
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationService.java
@@ -0,0 +1,52 @@
+package eu.europa.ec.edelivery.smp.auth;
+
+import eu.europa.ec.edelivery.smp.data.ui.UserRO;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Service;
+
+import static eu.europa.ec.edelivery.smp.auth.SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN;
+import static java.util.stream.Collectors.toList;
+
+/**
+ * @author Sebastian-Ion TINCU
+ */
+@Service("smpAuthorizationService")
+public class SMPAuthorizationService {
+
+    public boolean isSystemAdministrator() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        return authentication instanceof SMPAuthenticationToken
+                && authentication.getAuthorities().stream().anyMatch(grantedAuthority -> S_AUTHORITY_TOKEN_SYSTEM_ADMIN.equals(grantedAuthority.getAuthority()));
+    }
+
+    public boolean isCurrentlyLoggedIn(Long userId) {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        if(authentication instanceof SMPAuthenticationToken) {
+            Long loggedInUserId = ((SMPAuthenticationToken) authentication).getUser().getId();
+            return loggedInUserId.equals(userId);
+        }
+
+        return false;
+    }
+    /**
+     * Returns a user resource with password credentials removed and authorities populated for use in the front-end.
+     *
+     * @param userRO The user resource to sanitize for use in the front-end.
+     * @return the sanitized user resource
+     */
+    public UserRO sanitize(UserRO userRO) {
+        userRO.setPassword("");
+
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        if(authentication instanceof SMPAuthenticationToken) {
+            userRO.setAuthorities(
+                    authentication.getAuthorities()
+                            .stream()
+                            .map(authority -> authority.getAuthority())
+                            .collect(toList()));
+        }
+
+        return userRO;
+    }
+}
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SmpWebAppConfig.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SmpWebAppConfig.java
index abe9526b17b6d1efb8d0f2135573a3707c71af03..cac805896d084a49c82bf4c970ec23095aa04335 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SmpWebAppConfig.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SmpWebAppConfig.java
@@ -42,6 +42,7 @@ import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;
 @ComponentScan(basePackages = {
         "eu.europa.ec.edelivery.smp.controllers",
         "eu.europa.ec.edelivery.smp.validation",
+        "eu.europa.ec.edelivery.smp.conversion",
         "eu.europa.ec.edelivery.smp.monitor",
         "eu.europa.ec.edelivery.smp.ui"})
 @Import({GlobalMethodSecurityConfig.class, ErrorMappingControllerAdvice.class})
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java
index 3a80d1972eb96f6d379d7f1875bdea647d10aa0b..2ae1ded9b8f3c5de61e71199635b8a0f58412433 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java
@@ -1,14 +1,17 @@
 package eu.europa.ec.edelivery.smp.ui;
 
 
+import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationService;
+import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationToken;
 import eu.europa.ec.edelivery.smp.auth.SMPAuthority;
+import eu.europa.ec.edelivery.smp.auth.SMPAuthorizationService;
 import eu.europa.ec.edelivery.smp.data.ui.ErrorRO;
 import eu.europa.ec.edelivery.smp.data.ui.LoginRO;
 import eu.europa.ec.edelivery.smp.data.ui.UserRO;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
-import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.convert.ConversionService;
 import org.springframework.http.HttpStatus;
 import org.springframework.security.access.annotation.Secured;
 import org.springframework.security.authentication.BadCredentialsException;
@@ -23,8 +26,6 @@ import org.springframework.web.bind.annotation.*;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import static java.util.stream.Collectors.toList;
-
 /**
  * @author Sebastian-Ion TINCU
  * @since 4.0
@@ -38,6 +39,12 @@ public class AuthenticationResource {
     @Autowired
     protected SMPAuthenticationService authenticationService;
 
+    @Autowired
+    protected SMPAuthorizationService authorizationService;
+
+    @Autowired
+    private ConversionService conversionService;
+
     @ResponseStatus(value = HttpStatus.FORBIDDEN)
     @ExceptionHandler({AuthenticationException.class})
     public ErrorRO handleException(Exception ex) {
@@ -49,16 +56,9 @@ public class AuthenticationResource {
     @Transactional(noRollbackFor = BadCredentialsException.class)
     public UserRO authenticate(@RequestBody LoginRO loginRO, HttpServletResponse response) {
         LOG.debug("Authenticating user [{}]", loginRO.getUsername());
-        final Authentication principal = authenticationService.authenticate(loginRO.getUsername(), loginRO.getPassword());
-
-        UserRO userRO = new UserRO();
-        userRO.setUsername(loginRO.getUsername());
-        userRO.setAuthorities(
-                principal.getAuthorities()
-                        .stream()
-                        .map(authority -> authority.getAuthority())
-                        .collect(toList()));
-        return userRO;
+        SMPAuthenticationToken authentication = (SMPAuthenticationToken) authenticationService.authenticate(loginRO.getUsername(), loginRO.getPassword());
+        UserRO userRO = conversionService.convert(authentication.getUser(), UserRO.class);
+        return authorizationService.sanitize(userRO);
     }
 
     @RequestMapping(value = "authentication", method = RequestMethod.DELETE)
@@ -76,18 +76,16 @@ public class AuthenticationResource {
         LOG.info("Logged out");
     }
 
-   // @PutMapping(produces = {"text/plain"})
     @RequestMapping(value = "user", method = RequestMethod.GET)
     @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN})
     public UserRO getUser() {
-      //  User securityUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
-        //return securityUser.getUsername();
-        String username = (String)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
-        System.out.println("get user: " + username);
-        UserRO ur =new UserRO();
-        ur.setUsername(username);
-        return ur;
+        UserRO user = new UserRO();
+
+        String username = (String) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        LOG.debug("get user: {}", username);
 
+        user.setUsername(username);
+        return user;
     }
 
 }
\ No newline at end of file
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/UserResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/UserResource.java
index affa1fbd042b4c456316d036f4d51a259aedc6c0..8fd5eeac096722b846c17f6fc81441318d7532f1 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/UserResource.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/UserResource.java
@@ -1,9 +1,8 @@
 package eu.europa.ec.edelivery.smp.ui;
 
-
 import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationToken;
 import eu.europa.ec.edelivery.smp.auth.SMPAuthority;
-import eu.europa.ec.edelivery.smp.auth.SMPRole;
+import eu.europa.ec.edelivery.smp.auth.SMPAuthorizationService;
 import eu.europa.ec.edelivery.smp.data.model.DBUser;
 import eu.europa.ec.edelivery.smp.data.ui.CertificateRO;
 import eu.europa.ec.edelivery.smp.data.ui.DeleteEntityValidation;
@@ -15,11 +14,12 @@ import eu.europa.ec.edelivery.smp.services.ui.UIUserService;
 import eu.europa.ec.edelivery.smp.services.ui.filters.UserFilter;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.annotation.Secured;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.crypto.bcrypt.BCrypt;
 import org.springframework.web.bind.annotation.*;
 
-import javax.annotation.PostConstruct;
 import java.io.IOException;
 import java.security.cert.CertificateException;
 import java.util.Arrays;
@@ -29,7 +29,6 @@ import java.util.List;
  * @author Joze Rihtarsic
  * @since 4.1
  */
-
 @RestController
 @RequestMapping(value = "/ui/rest/user")
 public class UserResource {
@@ -39,15 +38,11 @@ public class UserResource {
     @Autowired
     private UIUserService uiUserService;
 
-    @PostConstruct
-    protected void init() {
-
-    }
+    @Autowired
+    protected SMPAuthorizationService authorizationService;
 
     @PutMapping(produces = {"application/json"})
-    @ResponseBody
     @RequestMapping(method = RequestMethod.GET)
-    //update gui to call this when somebody is logged in.
     @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN})
     public ServiceResult<UserRO> getUsers(
             @RequestParam(value = "page", defaultValue = "0") int page,
@@ -56,8 +51,8 @@ public class UserResource {
             @RequestParam(value = "orderType", defaultValue = "asc", required = false) String orderType,
             @RequestParam(value = "roles", required = false) String roleList
             ) {
-        UserFilter filter =null;
-        if (roleList!=null){
+        UserFilter filter = null;
+        if (roleList != null) {
             filter = new UserFilter();
             filter.setRoleList(Arrays.asList(roleList.split(",")));
         }
@@ -65,17 +60,37 @@ public class UserResource {
         return  uiUserService.getTableList(page,pageSize, orderBy, orderType, filter);
     }
 
+    /**
+     * Update the details of the currently logged in user (e.g. update the role, the credentials or add certificate details).
+     *
+     * @param id the identifier of the user being updated; it must match the currently logged in user's identifier
+     * @param user the updated details
+     *
+     * @throws org.springframework.security.access.AccessDeniedException when trying to update the details of another user, different than the one being currently logged in
+     */
+    @PutMapping(path = "/{id}")
+    @PreAuthorize("@smpAuthorizationService.isCurrentlyLoggedIn(#id)")
+    public UserRO updateCurrentUser(@PathVariable("id") Long id, @RequestBody UserRO user) {
+        LOG.info("Update current user: {}", user);
+
+        uiUserService.updateUserList(Arrays.asList(user));
+
+        DBUser updatedUser = uiUserService.findUser(id);
+        UserRO userRO = uiUserService.convertToRo(updatedUser);
+
+        return authorizationService.sanitize(userRO);
+    }
+
     @PutMapping(produces = {"application/json"})
-    @RequestMapping(method = RequestMethod.PUT)
     @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN})
-    public void updateUserList(@RequestBody(required = true) UserRO[] updateEntities ){
-        LOG.info("Update user list, count: {}" + updateEntities.length);
+    public void updateUserList(@RequestBody UserRO[] updateEntities ){
+        LOG.info("Update user list, count: {}", updateEntities.length);
         uiUserService.updateUserList(Arrays.asList(updateEntities));
     }
 
-    @RequestMapping(path = "certdata", method = RequestMethod.POST)
-    @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN})
-    public CertificateRO uploadFile(@RequestBody byte[] data) {
+    @PostMapping("/{id}/certdata")
+    @PreAuthorize("@smpAuthorizationService.systemAdministrator || @smpAuthorizationService.isCurrentlyLoggedIn(#id)")
+    public CertificateRO uploadFile(@PathVariable("id") Long id, @RequestBody byte[] data) {
         LOG.info("Got certificate data: " + data.length);
         try {
             return uiUserService.getCertificateData(data);
@@ -83,17 +98,21 @@ public class UserResource {
             LOG.error("Error occurred while parsing certificate.", e);
         }
         return null;
+    }
 
+    @PostMapping(path = "/{id}/samePreviousPasswordUsed", produces = {"application/json"})
+    @PreAuthorize("@smpAuthorizationService.isCurrentlyLoggedIn(#id)")
+    public boolean samePreviousPasswordUsed(@PathVariable("id") Long id, @RequestBody String password) {
+        LOG.info("Validating the password of the currently logged in user: {} ", id);
+        DBUser user = uiUserService.findUser(getCurrentUser().getId());
+        return BCrypt.checkpw(password, user.getPassword());
     }
 
     @PutMapping(produces = {"application/json"})
     @RequestMapping(path = "validateDelete", method = RequestMethod.POST)
     @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN})
     public DeleteEntityValidation validateDeleteUsers(@RequestBody List<Long> query) {
-        // test if looged user
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-        SMPAuthenticationToken authToken = (SMPAuthenticationToken) authentication;
-        DBUser user = authToken.getUser();
+        DBUser user = getCurrentUser();
         DeleteEntityValidation dres = new DeleteEntityValidation();
         if (query.contains(user.getId())){
             dres.setValidOperation(false);
@@ -103,4 +122,10 @@ public class UserResource {
         dres.getListIds().addAll(query);
         return uiUserService.validateDeleteRequest(dres);
     }
+
+    private DBUser getCurrentUser() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        SMPAuthenticationToken authToken = (SMPAuthenticationToken) authentication;
+        return authToken.getUser();
+    }
 }