diff --git a/.gitignore b/.gitignore
index 072c92ae016cc899a2656a9d702df426f841b596..73684590bf1425b88b86403ade3e50158c30a665 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,32 +1,41 @@
-common/cipa-commons-busdox/target/
-common/cipa-edelivery-common/target/classes/eu/europa/ec/cipa/common/business/AbstractBusinessImpl.class
-common/cipa-edelivery-common/target/classes/eu/europa/ec/cipa/common/exception/BusinessException.class
-common/cipa-edelivery-common/target/classes/eu/europa/ec/cipa/common/logging/ILogEvent.class
-common/cipa-edelivery-common/target/classes/eu/europa/ec/cipa/common/logging/impl/AbstractLoggerImpl.class
-common/cipa-edelivery-common/target/classes/eu/europa/ec/cipa/common/logging/impl/LoggingServiceImpl.class
-common/cipa-edelivery-common/target/
-common/cipa-peppol-types/target/
-sml/cipa-sml-client-library/target/
-sml/cipa-sml-server-library/target/
-sml/cipa-sml-webapp/target/
-smp/.idea/libraries/Maven__com_sun_jersey_jersey_client_1_17_1.xml
-smp/.idea/libraries/
-smp/cipa-smp-client-library/target/
-smp/cipa-smp-full-webapp/target/
-smp/cipa-smp-readonly-webapp/target/
-smp/cipa-smp-server-library/target/
-smp/.idea/
-smp-api/target/
-smp-api/.idea/copyright/profiles_settings.xml
-smp-api/.idea/libraries/Maven__junit_junit_4_12.xml
-smp-api/.idea/libraries/
-smp-api/.idea/
-*.iml
-addons/cipa-sml-util/.idea/
-addons/cipa-sml-util/target/
-addons/cipa-sml-migration/target/test-classes/global-truststore.jks
-addons/cipa-sml-migration/target/classes/
-addons/cipa-sml-migration/target/
-addons/cipa-sml-migration/.idea/
+## Eclipse config files ##
+.settings/
+.classpath
+.project
+
+## PMD Eclipse plugin files ##
+.pmd
+
+## Maven output folder ##
+target/
+
+#temporary output of the cargo plugin
+cargo
+
+## Compiled java classes ##
+*.class
+*.jar
+*.war
+*.ear
+
+## generic files to ignore
+*~
+*.lock
+*.DS_Store
+*.swp
+*.out
+*.tmp
+*.log
+
+## Intellij IDEA files 
 .idea/
-code-coverage
\ No newline at end of file
+*.iml
+*.ipr
+*.iws
+
+## Files generated by checksum plugin
+*.sha256
+
+## maven-shade-plugin generated files
+dependency-reduced-pom.xml
+/.idea/
diff --git a/pom.xml b/pom.xml
index 870d255edd7e3b714f50fc79addee7a884a5406d..1d6b279c055c7b2ac6473b1546ce014ef4596ac5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,6 +66,7 @@
         <jackson.version>2.13.2</jackson.version>
         <javaee-api.version>7.0</javaee-api.version>
         <javax.annotation.version>1.3.2</javax.annotation.version>
+        <javax.mail.version>1.6.2</javax.mail.version>
         <jaxb.version>2.2.11</jaxb.version>
         <jaxb2-basics.version>1.11.1</jaxb2-basics.version>
         <jstl.version>1.2</jstl.version>
@@ -89,8 +90,22 @@
 
         <sonar.host.url>http://localhost:9000/sonar/</sonar.host.url>
         <sonar.language>java</sonar.language>
+
+        <sonar.binaries>target/classes</sonar.binaries>
+        <sonar.coverage.jacoco.xmlReportPaths>${project.basedir}/target/site/jacoco/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
         <jacoco.maven.plugin.version>0.8.6</jacoco.maven.plugin.version>
         <surefire.maven.plugin.version>2.22.2</surefire.maven.plugin.version>
+        <sonar.exclusions>
+            **/target/**,
+            **/smp-angular/node_modules/**,
+            **/swagger*.js,
+            **/web.xml,
+        </sonar.exclusions>
+        <sonar.coverage.exclusions>
+            **/*Entity.java,
+            **/*RO.java,
+            **/*Exception.java,
+        </sonar.coverage.exclusions>
         <!-- latest version compatible with SonarQube 5.6 is: 3.3.0.603-->
         <sonar.maven.plugin.version>3.5.0.1254</sonar.maven.plugin.version>
     </properties>
@@ -374,7 +389,7 @@
             <dependency>
                 <groupId>com.sun.mail</groupId>
                 <artifactId>javax.mail</artifactId>
-                <version>1.6.2</version>
+                <version>${javax.mail.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.mockito</groupId>
diff --git a/smp-angular/src/app/domain/domain-controller.ts b/smp-angular/src/app/domain/domain-controller.ts
index aa87bf865a973b3b5004d7ba184cba861aca03f9..152f522e60e738a31ce32af4d530f93a02b53391 100644
--- a/smp-angular/src/app/domain/domain-controller.ts
+++ b/smp-angular/src/app/domain/domain-controller.ts
@@ -45,7 +45,7 @@ export class DomainController implements SearchTableController {
       signatureKeyAlias: '',
       status: SearchTableEntityStatus.NEW,
       smlRegistered: false,
-      smlBlueCoatAuth: false,
+      smlClientCertAuth: false,
     }
   }
   public dataSaved() {
diff --git a/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.html b/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.html
index d04934b9041353e2aba90ad033104843e7b328fa..1f30f9c8369a1dbfc7562ee63c3e51c18f7d12b8 100644
--- a/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.html
+++ b/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.html
@@ -102,13 +102,13 @@
           <mat-form-field style="width:100%"
                           matTooltip="SML Client-Cert http Header used for SML authentication. The header is generated from chosen  SML ClientCert Alias">
             <input matInput placeholder="SML ClientCert Header" name="Client certificate" id="smlClientHeader_id"
-                   [value]="selectedSMLCert?.blueCoatHeader" maxlength="2000" readonly="true">
+                   [value]="selectedSMLCert?.clientCertHeader" maxlength="2000" readonly="true">
           </mat-form-field>
 
           <mat-slide-toggle style="width:100%"
-                            mat-no-ink class="mat-primary" [formControl]="domainForm.controls['smlBlueCoatAuth']"
-                            id="smlBlueCoatAuth_id">
-            Use blueCoat http header authentication.
+                            mat-no-ink class="mat-primary" [formControl]="domainForm.controls['smlClientCertAuth']"
+                            id="smlClientCertHeaderAuth_id">
+            Use ClientCert http header authentication.
           </mat-slide-toggle>
 
         </fieldset>
diff --git a/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.ts b/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.ts
index c9ea404e8b3f8598848ae283f9a8eb9b01a53882..65bddca78be126634b59ea62147d6ed238d05f56 100644
--- a/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.ts
+++ b/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.ts
@@ -77,7 +77,7 @@ export class DomainDetailsDialogComponent {
       'signatureKeyAlias': new FormControl({value: ''}, null),
 
       'smlRegistered': new FormControl({value: ''}, null),
-      'smlBlueCoatAuth': new FormControl({value: ''}, null),
+      'smlClientCertAuth': new FormControl({value: ''}, null),
 
     });
 
@@ -90,7 +90,7 @@ export class DomainDetailsDialogComponent {
     this.domainForm.controls['signatureKeyAlias'].setValue(this.current.signatureKeyAlias);
 
     this.domainForm.controls['smlRegistered'].setValue(this.current.smlRegistered);
-    this.domainForm.controls['smlBlueCoatAuth'].setValue(this.current.smlBlueCoatAuth);
+    this.domainForm.controls['smlClientCertAuth'].setValue(this.current.smlClientCertAuth);
 
     if (this.current.smlClientKeyAlias) {
       this.selectedSMLCert = this.lookups.cachedCertificateList.find(crt => crt.alias === this.current.smlClientKeyAlias);
@@ -145,13 +145,13 @@ export class DomainDetailsDialogComponent {
     this.current.smlClientCertHeader = this.domainForm.value['smlClientCertHeader'];
     if (this.domainForm.value['smlClientKeyCertificate']) {
       this.current.smlClientKeyAlias = this.domainForm.value['smlClientKeyCertificate'].alias;
-      this.current.smlClientCertHeader = this.domainForm.value['smlClientKeyCertificate'].blueCoatHeader;
+      this.current.smlClientCertHeader = this.domainForm.value['smlClientKeyCertificate'].clientCertHeader;
     } else {
       this.current.smlClientKeyAlias = '';
       this.current.smlClientCertHeader = '';
     }
     this.current.signatureKeyAlias = this.domainForm.value['signatureKeyAlias'];
-    this.current.smlBlueCoatAuth = this.domainForm.value['smlBlueCoatAuth'];
+    this.current.smlClientCertAuth = this.domainForm.value['smlClientCertAuth'];
 
     return this.current;
 
diff --git a/smp-angular/src/app/domain/domain-ro.model.ts b/smp-angular/src/app/domain/domain-ro.model.ts
index f27b18f91a21a4c814aa8508a3b404444a35db41..3f8ce5e6b2933c2eacfb24d8f530748966d4e7ff 100644
--- a/smp-angular/src/app/domain/domain-ro.model.ts
+++ b/smp-angular/src/app/domain/domain-ro.model.ts
@@ -9,6 +9,6 @@ export interface DomainRo extends SearchTableEntity {
   smlClientKeyAlias: string;
   signatureKeyAlias: string;
   smlRegistered: boolean;
-  smlBlueCoatAuth: boolean;
+  smlClientCertAuth: boolean;
 }
 
diff --git a/smp-angular/src/app/domain/domain.component.ts b/smp-angular/src/app/domain/domain.component.ts
index cf834ada45cb1af202991a127bee665e7562cc8f..6f57cccb9d5f86e28b22145b812893cc54dec1ca 100644
--- a/smp-angular/src/app/domain/domain.component.ts
+++ b/smp-angular/src/app/domain/domain.component.ts
@@ -1,4 +1,4 @@
-import {AfterViewInit, Component, OnInit, TemplateRef, ViewChild} from '@angular/core';
+import {AfterViewInit, Component, TemplateRef, ViewChild} from '@angular/core';
 import {ColumnPicker} from '../common/column-picker/column-picker.model';
 import {MatDialog, MatDialogRef} from '@angular/material/dialog';
 
@@ -14,7 +14,6 @@ import {ConfirmationDialogComponent} from "../common/confirmation-dialog/confirm
 import {SearchTableEntityStatus} from "../common/search-table/search-table-entity-status.model";
 import {KeystoreEditDialogComponent} from "./keystore-edit-dialog/keystore-edit-dialog.component";
 import {SmpInfoService} from "../app-info/smp-info.service";
-import {SmpInfo} from "../app-info/smp-info.model";
 import {SmlIntegrationService} from "./sml-integration.service";
 import {SMLResult} from "./sml-result.model";
 
@@ -36,8 +35,6 @@ export class DomainComponent implements AfterViewInit {
   columnPicker: ColumnPicker = new ColumnPicker();
   domainController: DomainController;
   filter: any = {};
-  isSMPIntegrationOn: boolean = false;
-
 
   constructor(public securityService: SecurityService,
               protected smpInfoService: SmpInfoService,
@@ -48,11 +45,8 @@ export class DomainComponent implements AfterViewInit {
               public dialog: MatDialog) {
 
     // check application settings
-    this.isSMPIntegrationOn = this.lookups.cachedApplicationConfig.smlIntegrationOn
-    // if system admin refresh certificate list!
-    if (this.securityService.isCurrentUserSystemAdmin()) {
-      this.lookups.refreshCertificateLookup();
-    }
+
+
   }
 
   ngAfterViewInit() {
@@ -104,14 +98,20 @@ export class DomainComponent implements AfterViewInit {
         width: 120
       },
       {
-        name: 'SML BueCoat Auth.',
-        prop: 'smlBlueCoatAuth',
+        name: 'SML ClientCert Auth.',
+        prop: 'smlClientCertAuth',
         showInitially: true,
         width: 130
       },
     ];
     this.searchTable.tableColumnInit();
     this.columnPicker.selectedColumns = this.columnPicker.allColumns.filter(col => col.showInitially);
+
+    // if system admin refresh certificate list!
+    if (this.securityService.isCurrentUserSystemAdmin()) {
+      this.lookups.refreshCertificateLookup();
+    }
+
   }
 
   certificateAliasExists(alias: string): boolean {
@@ -146,14 +146,15 @@ export class DomainComponent implements AfterViewInit {
       return 'deleted';
     }
   }
+
   getDomainConfigurationWarning(domain: DomainRo) {
-    let msg =null;
+    let msg = null;
     if (!domain.signatureKeyAlias) {
       msg = "The domain should have a defined signature CertAlias."
     }
     if (this.lookups.cachedApplicationConfig.smlIntegrationOn) {
-      if( !domain.smlSmpId || !domain.smlClientCertHeader){
-        msg = (!msg?"": msg+" ") + "For SML integration the SMP SMP ID and SML client certificate must be defined!"
+      if (!domain.smlSmpId || !domain.smlClientCertHeader) {
+        msg = (!msg ? "" : msg + " ") + "For SML integration the SMP SMP ID and SML client certificate must be defined!"
       }
     }
     return msg;
@@ -167,6 +168,9 @@ export class DomainComponent implements AfterViewInit {
   isDirty(): boolean {
     return this.searchTable.isDirty();
   }
+  get isSMPIntegrationOn(){
+    return this.lookups.cachedApplicationConfig?.smlIntegrationOn
+  }
 
   enableSMLRegister(): boolean {
     if (!this.selectedOneRow || !this.isSMPIntegrationOn) {
@@ -174,10 +178,10 @@ export class DomainComponent implements AfterViewInit {
     }
     let domainRo = (this.searchTable.selected[0] as DomainRo);
 
-    if (!domainRo.smlClientCertHeader && domainRo.smlBlueCoatAuth) {
+    if (!domainRo.smlClientCertHeader && domainRo.smlClientCertAuth) {
       return false;
     }
-    if (!domainRo.smlClientKeyAlias && !domainRo.smlBlueCoatAuth) {
+    if (!domainRo.smlClientKeyAlias && !domainRo.smlClientCertAuth) {
       return false;
     }
 
@@ -189,15 +193,15 @@ export class DomainComponent implements AfterViewInit {
   }
 
   enableSMLUnregister(): boolean {
-    if ( !this.selectedOneRow || !this.isSMPIntegrationOn) {
+    if (!this.selectedOneRow || !this.isSMPIntegrationOn) {
       return false;
     }
     let domainRo = (this.searchTable.selected[0] as DomainRo);
 
-    if (!domainRo.smlClientCertHeader && domainRo.smlBlueCoatAuth) {
+    if (!domainRo.smlClientCertHeader && domainRo.smlClientCertAuth) {
       return false;
     }
-    if (!domainRo.smlClientKeyAlias && !domainRo.smlBlueCoatAuth) {
+    if (!domainRo.smlClientKeyAlias && !domainRo.smlClientCertAuth) {
       return false;
     }
 
@@ -209,7 +213,7 @@ export class DomainComponent implements AfterViewInit {
     return domainRo.smlRegistered;
   }
 
-  get selectedOneRow() : boolean{
+  get selectedOneRow(): boolean {
     return this.searchTable?.selected.length === 1
   }
 
@@ -252,9 +256,9 @@ export class DomainComponent implements AfterViewInit {
   }
 
   smlRegisterDomain(domain: DomainRo) {
-    this.searchTable.showSpinner=true;
+    this.searchTable.showSpinner = true;
     this.smlIntegrationService.registerDomainToSML$(domain.domainCode).toPromise().then((res: SMLResult) => {
-        this.searchTable.showSpinner=false;
+        this.searchTable.showSpinner = false;
         if (res) {
           if (res.success) {
             this.alertService.success("Domain " + domain.domainCode + " registered to sml!");
@@ -268,16 +272,16 @@ export class DomainComponent implements AfterViewInit {
         }
       },
       err => {
-        this.searchTable.showSpinner=false;
+        this.searchTable.showSpinner = false;
         this.alertService.exception('Error occurred while registering domain:' + domain.domainCode, err);
       }
     )
   }
 
   smlUnregisterDomain(domain: DomainRo) {
-    this.searchTable.showSpinner=true;
+    this.searchTable.showSpinner = true;
     this.smlIntegrationService.unregisterDomainToSML$(domain.domainCode).toPromise().then((res: SMLResult) => {
-        this.searchTable.showSpinner=false;
+        this.searchTable.showSpinner = false;
         if (res) {
           if (res.success) {
             this.alertService.success("Domain " + domain.domainCode + " unregistered from sml!");
@@ -292,7 +296,7 @@ export class DomainComponent implements AfterViewInit {
       }
       ,
       err => {
-        this.searchTable.showSpinner=false;
+        this.searchTable.showSpinner = false;
         this.alertService.exception('Error occurred while unregistering domain:' + domain.domainCode, err);
       }
     )
diff --git a/smp-angular/src/app/property/property-details-dialog/property-details-dialog.component.html b/smp-angular/src/app/property/property-details-dialog/property-details-dialog.component.html
index 7855da5ad0bab57f63308be6ab439b48bdab85d6..80a8076de4992465d349e615c7966f0c48b14db4 100644
--- a/smp-angular/src/app/property/property-details-dialog/property-details-dialog.component.html
+++ b/smp-angular/src/app/property/property-details-dialog/property-details-dialog.component.html
@@ -13,12 +13,15 @@
           <mat-label>Property value:</mat-label>
           <input
             matInput type="{{ getInputType(propertyForm.controls['type'].value) }}" style="width: 100%;padding: 5px"
-            formControlName="value"/>
+            formControlName="value" [pattern]="propertyForm.controls['valuePattern'].value"/>
         </mat-form-field>
         <mat-checkbox *ngIf="propertyForm.controls['type'].value === 'BOOLEAN'"
                       formControlName="value" >
           {{ propertyForm.controls['property'].value }}
         </mat-checkbox>
+        <div *ngIf="propertyForm.controls['errorMessage'].value" class="alert-message-error">
+          {{ propertyForm.controls['errorMessage'].value}}
+        </div>
       </mat-card-content>
     </mat-card>
   </form>
diff --git a/smp-angular/src/app/property/property-details-dialog/property-details-dialog.component.ts b/smp-angular/src/app/property/property-details-dialog/property-details-dialog.component.ts
index 58eee4d030b80b741ebab907d354882da6be83bb..2d3b141895698aa4276ad2f4599ae97ddd026742 100644
--- a/smp-angular/src/app/property/property-details-dialog/property-details-dialog.component.ts
+++ b/smp-angular/src/app/property/property-details-dialog/property-details-dialog.component.ts
@@ -4,6 +4,11 @@ import {FormBuilder, FormControl, FormGroup} from "@angular/forms";
 import {PropertyRo} from "../property-ro.model";
 import {AlertMessageService} from "../../common/alert-message/alert-message.service";
 import {SearchTableEntityStatus} from "../../common/search-table/search-table-entity-status.model";
+import {ServiceGroupValidationRo} from "../../service-group-edit/service-group-details-dialog/service-group-validation-edit-ro.model";
+import {SmpConstants} from "../../smp.constants";
+import {ServiceGroupValidationErrorCodeModel} from "../../service-group-edit/service-group-details-dialog/service-group-validation-error-code.model";
+import {PropertyValidationRo} from "../property-validate-ro.model";
+import {HttpClient} from "@angular/common/http";
 
 @Component({
   selector: 'property-details-dialog',
@@ -21,10 +26,12 @@ export class PropertyDetailsDialogComponent implements OnInit {
   current: PropertyRo & { confirmation?: string };
   propertyForm: FormGroup;
   disabled: true;
+  showSpinner: boolean = false;
 
 
   constructor(
     public dialog: MatDialog,
+    protected http: HttpClient,
     private dialogRef: MatDialogRef<PropertyDetailsDialogComponent>,
     private alertService: AlertMessageService,
     @Inject(MAT_DIALOG_DATA) public data: any,
@@ -50,6 +57,8 @@ export class PropertyDetailsDialogComponent implements OnInit {
       'desc': new FormControl({value: '', readonly: true}, null),
       'type': new FormControl({value: '', readonly: true}, null),
       'value': new FormControl({value: ''}),
+      'valuePattern': new FormControl({value: ''}),
+      'errorMessage': new FormControl({value: ''}),
 
     });
 
@@ -57,6 +66,9 @@ export class PropertyDetailsDialogComponent implements OnInit {
     this.propertyForm.controls['desc'].setValue(this.current.desc);
     this.propertyForm.controls['type'].setValue(this.current.type);
     this.propertyForm.controls['value'].setValue(this.valueFromPropertyStringValue(this.current.value, this.current.type));
+    this.propertyForm.controls['valuePattern'].setValue(this.current.valuePattern);
+
+    this.propertyForm.controls['errorMessage'].setValue('');
   }
 
   ngOnInit() {
@@ -64,9 +76,26 @@ export class PropertyDetailsDialogComponent implements OnInit {
   }
 
   submitForm() {
-    this.checkValidity(this.propertyForm)
-    this.dialogRef.close(true);
-
+    this.checkValidity(this.propertyForm);
+
+    let request =  this.getCurrent();
+    //
+    let validationObservable = this.http.post<PropertyValidationRo>(SmpConstants.REST_INTERNAL_PROPERTY_VALIDATE, request);
+    this.showSpinner = true;
+    validationObservable.toPromise().then((res: PropertyValidationRo) => {
+      this.showSpinner = false;
+
+      if (!res.propertyValid) {
+        this.propertyForm.controls['errorMessage'].setValue(res.errorMessage?res.errorMessage:'Invalid property');
+      } else {
+        this.propertyForm.controls['errorMessage'].setValue("");
+        // we can close the dialog
+        this.dialogRef.close(true);
+      }
+    }).catch((err) => {
+      this.alertService.error("Error occurred on Validation the property", err)
+      console.log("Error occurred on Validation the property: " + err);
+    });
   }
 
   checkValidity(g: FormGroup) {
@@ -115,7 +144,7 @@ export class PropertyDetailsDialogComponent implements OnInit {
       case 'PATH':
         return 'text';
       case 'INTEGER':
-        return 'number';
+        return 'text';
       case 'BOOLEAN':
         return 'checkbox';
       case 'REGEXP':
@@ -128,6 +157,29 @@ export class PropertyDetailsDialogComponent implements OnInit {
         return 'text';
     }
   }
+  getInputPatternType(propertyType: string) {
+    console.log("Get input pattern for row " + this.current.type)
+    switch (propertyType) {
+      case 'STRING':
+      case 'LIST_STRING':
+      case 'MAP_STRING':
+      case 'FILENAME':
+      case 'PATH':
+        return '';
+      case 'INTEGER':
+        return '[0-9]*';
+      case 'BOOLEAN':
+        return 'true/false';
+      case 'REGEXP':
+        return '';
+      case 'EMAIL':
+        return '';
+      case 'URL':
+        return '';
+      default:
+        return '';
+    }
+  }
 
   public getCurrent(): PropertyRo {
     this.current.value = this.propertyForm.value['value'];
diff --git a/smp-angular/src/app/property/property-ro.model.ts b/smp-angular/src/app/property/property-ro.model.ts
index 043f894f4b51b68c7e6b4e2306387e6220a27d7e..d8663bcf39e740f7c36b935719373a8f7016c1b7 100644
--- a/smp-angular/src/app/property/property-ro.model.ts
+++ b/smp-angular/src/app/property/property-ro.model.ts
@@ -10,4 +10,5 @@ export interface PropertyRo extends SearchTableEntity {
   updateDate?: Date;
   mandatory?: boolean;
   restartNeeded? : boolean;
+  valuePattern?:string;
 }
diff --git a/smp-angular/src/app/property/property-validate-ro.model.ts b/smp-angular/src/app/property/property-validate-ro.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bdbbb4b563239b69d15cbb30559b1e297297db6f
--- /dev/null
+++ b/smp-angular/src/app/property/property-validate-ro.model.ts
@@ -0,0 +1,8 @@
+import {SearchTableEntity} from '../common/search-table/search-table-entity.model';
+
+export interface PropertyValidationRo  {
+  property: string;
+  value?: string;
+  propertyValid : boolean;
+  errorMessage?: string;
+}
diff --git a/smp-angular/src/app/smp.constants.ts b/smp-angular/src/app/smp.constants.ts
index 921547f22330c96f49db65544c3671bf198f72fb..7038d8a5de1b0f1e1cfe43b53af38b3503c0995f 100644
--- a/smp-angular/src/app/smp.constants.ts
+++ b/smp-angular/src/app/smp.constants.ts
@@ -40,6 +40,7 @@ export class SmpConstants {
   public static readonly REST_INTERNAL_ALERT_MANAGE = SmpConstants.REST_INTERNAL + 'alert';
   public static readonly REST_INTERNAL_DOMAIN_MANAGE = SmpConstants.REST_INTERNAL + 'domain';
   public static readonly REST_INTERNAL_PROPERTY_MANAGE = SmpConstants.REST_INTERNAL + 'property';
+  public static readonly REST_INTERNAL_PROPERTY_VALIDATE = SmpConstants.REST_INTERNAL_PROPERTY_MANAGE + '/validate';
   public static readonly REST_INTERNAL_DOMAIN_VALIDATE_DELETE = SmpConstants.REST_INTERNAL_DOMAIN_MANAGE + '/validate-delete';
   public static readonly REST_INTERNAL_USER_MANAGE = SmpConstants.REST_INTERNAL + 'user';
   public static readonly REST_INTERNAL_USER_VALIDATE_DELETE = `${SmpConstants.REST_INTERNAL_USER_MANAGE}/validate-delete`;
diff --git a/smp-angular/src/app/user/certificate-ro.model.ts b/smp-angular/src/app/user/certificate-ro.model.ts
index a14dbb8b8ca66683701f4ebecf25dc98db2dc00a..7a0a8f1f8d6248999fb80c66d767ca45cc909de8 100644
--- a/smp-angular/src/app/user/certificate-ro.model.ts
+++ b/smp-angular/src/app/user/certificate-ro.model.ts
@@ -6,7 +6,7 @@ export interface CertificateRo {
   issuer: string;
   serialNumber: string;
   fingerprints: string;
-  blueCoatHeader?:string;
+  clientCertHeader?:string;
   encodedValue?:string;
   crlUrl?: String;
   alias?:string;
diff --git a/smp-angular/src/app/user/truststore-edit-dialog/truststore-edit-dialog.component.ts b/smp-angular/src/app/user/truststore-edit-dialog/truststore-edit-dialog.component.ts
index 8f9a3a2ce6e7509664374ccb00ef4f2848271e16..feab2a2dadeb9eec10fa05cc3383120af12ba2f3 100644
--- a/smp-angular/src/app/user/truststore-edit-dialog/truststore-edit-dialog.component.ts
+++ b/smp-angular/src/app/user/truststore-edit-dialog/truststore-edit-dialog.component.ts
@@ -77,6 +77,7 @@ export class TruststoreEditDialogComponent {
     const file = event.target.files[0];
     this.truststoreService.uploadCertificate$(file).subscribe((res: CertificateRo) => {
         if (res && res.certificateId) {
+          this.alertService.success("Certificate: " + res.certificateId + " is imported!");
           this.lookups.refreshTrustedCertificateLookup();
         } else {
           this.alertService.exception("Error occurred while uploading certificate.", "Check if uploaded file has valid certificate type.", false);
diff --git a/smp-api/pom.xml b/smp-api/pom.xml
index b75507ffc0334c5b2ff3672498ef3992e97429d8..c88981896b5c8b6346724e20ff7160de552b1d01 100644
--- a/smp-api/pom.xml
+++ b/smp-api/pom.xml
@@ -23,6 +23,7 @@
 
     <artifactId>smp-api</artifactId>
     <name>smp-api</name>
+    <packaging>jar</packaging>
 
     <dependencies>
         <!-- Generated equals() methods need it in runtime -->
diff --git a/smp-docker/compose/tomcat-mysql-smp-sml/README.md b/smp-docker/compose/tomcat-mysql-smp-sml/README.md
new file mode 100755
index 0000000000000000000000000000000000000000..4fd5846afc95ceccff6f53396dfbe74f5e124c47
--- /dev/null
+++ b/smp-docker/compose/tomcat-mysql-smp-sml/README.md
@@ -0,0 +1,54 @@
+# Experiamental SMP docker image
+Purpose of compose plan is to startup fully functinal SMP environment for demo and testing. The plan contains 
+ - MySql database
+ - SML services
+ - CAS instance (EULOGIN)
+ - email server (inbucket)
+
+
+# Run environment
+docker-compose -f docker-compose.yml up -d 
+
+
+## SMP 
+url: http://localhost:8982/smp/
+
+http://eulogin.protected.smp.local:8982/smp/
+eulogin.protected.smp.local
+
+### MYSQL 
+Database client connection (for testing and debugging )
+url: jdbc:mysql://localhost:3908/smp
+Username: smp
+Password: smp
+
+### Volume (-v /opt/dockerdata/sml:/data)
+Mysql database files and tomcat configuration (and logs) can be externalized for experimenting with different SMP settings.
+
+
+## SML 
+url: http://localhost:8982/edelivery-sml/
+
+### MYSQL 
+Database client connection (for testing and debugging )
+url: jdbc:mysql://localhost:3908/sml
+Username: sml
+Password: sml
+
+## CAS - EULOGIN 
+url: https://localhost:7102/cas/login
+Users:
+ - user/123456
+ - smp/123456
+ - system/123456
+
+ To use eulogin add the following hostname mappings (Linux: /etc/hosts, windows: C:\Windows\System32\drivers\etc\hosts
+                                                                                 
+                                                                                 and add the lines )
+ - 127.0.0.1 eulogin-mock-server
+ - 127.0.0.1 eulogin.protected.smp.local
+
+
+## Mail server
+url: http://172.19.0.2:9005/monitor 
+
diff --git a/smp-docker/compose/tomcat-mysql-smp-sml/docker-compose.yml b/smp-docker/compose/tomcat-mysql-smp-sml/docker-compose.yml
index 29724dc5598b2db50a870dbdc94c9ac9f5ad2a36..d4bc79f1d1cc3e5eb9cee8769416d6e29e91ad91 100644
--- a/smp-docker/compose/tomcat-mysql-smp-sml/docker-compose.yml
+++ b/smp-docker/compose/tomcat-mysql-smp-sml/docker-compose.yml
@@ -12,6 +12,19 @@ services:
         ||smp.sso.cas.urlpath.login=login
         ||smp.sso.cas.token.validation.urlpath=laxValidate
         ||smp.sso.cas.callback.url=http://eulogin.protected.smp.local:8982/smp/ui/public/rest/security/cas
+        ||bdmsl.integration.enabled=true
+        ||bdmsl.integration.url=http://localhost:8080/edelivery-sml/
+        ||mail.smtp.host=mail-server.smp.local
+        ||mail.smtp.port=2500
+        ||smp.alert.user.login_failure.enabled=true
+        ||smp.alert.user.suspended.enabled=true
+        ||smp.alert.password.imminent_expiration.enabled=true
+        ||smp.alert.password.expired.enabled=true
+        ||smp.alert.accessToken.imminent_expiration.enabled=true
+        ||smp.alert.accessToken.expired.enabled=true
+        ||smp.alert.certificate.imminent_expiration.enabled=true
+        ||smp.alert.certificate.expired.enabled=true
+        ||smp.alert.accessToken.expired.enabled=true
 
     volumes:
       - ./properties/db-scripts:/tmp/custom-data/
@@ -32,4 +45,10 @@ services:
  # Map this folder to host to be able to change runtime data for manual testing!
  #       - ./eulogin/ecas-mock-server:/data/ecas-mock-server
     ports:
-      - "7102:7102"
\ No newline at end of file
+      - "7102:7102"
+
+  mail-service:
+    image: inbucket/inbucket:3.0.0
+    hostname: mail-server.smp.local
+    ports:
+      - "9005:9000"
\ No newline at end of file
diff --git a/smp-docker/compose/tomcat-mysql-smp-sml/properties/db-scripts/sml-mysql5innodb-data.sql b/smp-docker/compose/tomcat-mysql-smp-sml/properties/db-scripts/sml-mysql5innodb-data.sql
index fe8a92272f55bef576413b723d3aeca21c6359ca..7b6b00682297623b2a335cd6bc57d7f281a90768 100644
--- a/smp-docker/compose/tomcat-mysql-smp-sml/properties/db-scripts/sml-mysql5innodb-data.sql
+++ b/smp-docker/compose/tomcat-mysql-smp-sml/properties/db-scripts/sml-mysql5innodb-data.sql
@@ -45,8 +45,11 @@ INSERT INTO bdmsl_certificate_domain(certificate, crl_url,  is_root_ca, fk_subdo
 ('CN=rootCNIsa,OU=B4,O=DIGIT,L=Brussels,ST=BE,C=BE','',1, 3, NOW(), NOW(),1),
 ('CN=AdministratorSML,OU=B4,O=DIGIT,C=BE','',0, 2, NOW(), NOW(),1);
 
+INSERT INTO bdmsl_certificate (id, certificate_id, valid_from ,valid_until,created_on, last_updated_on ) VALUES
+(id, 'CN=SMP_TEST-PRE-SET-EXAMPLE,O=DIGITAL,C=BE:00000000000000000000000000000001',DATE_ADD(NOW(), INTERVAL -3 DAY),DATE_ADD(NOW(), INTERVAL 365 DAY), NOW(), NOW());
 
-
+INSERT INTO bdmsl_smp (smp_id, fk_certificate_id, fk_subdomain_id, endpoint_logical_address, endpoint_physical_address, created_on, last_updated_on ) VALUES
+('CEF-SMP-001', 1,1, 'http://localhost:8080/smp/','0.0.0.0',NOW(), NOW());
 
 
 
diff --git a/smp-docker/images/build-docker-images.sh b/smp-docker/images/build-docker-images.sh
index 174e9bdbd48b474d8929cd0b8ed11354e69da8e2..79753c8ba20f3d3aa604542b81124b1cbec58792 100755
--- a/smp-docker/images/build-docker-images.sh
+++ b/smp-docker/images/build-docker-images.sh
@@ -53,6 +53,7 @@ while getopts v:o:s:c:p: option; do
   esac
 done
 
+
 if [[ -z "${SMP_VERSION}" ]]; then
   # get version from setup file
   echo "Get version from the pom: $(pwd)"
@@ -65,11 +66,14 @@ if [[ -z "${SMP_VERSION}" ]]; then
 
 fi
 
+SMP_PLUGIN_EXAMPLE="../../smp-examples/smp-spi-example/target/smp-spi-example-$SMP_VERSION.jar"
+
 DIRNAME=$(dirname "$0")
 cd "$DIRNAME"
 DIRNAME="$(pwd -P)"
 echo "*****************************************************************"
 echo "* SMP artefact folders: $SMP_ARTEFACTS, (Clear folder after build: $SMP_ARTEFACTS_CLEAR )"
+echo "* Plugin example: $SMP_PLUGIN_EXAMPLE "
 echo "* Build SMP image for version $SMP_VERSION"
 echo "* Oracle artefact folders: $ORACLE_ARTEFACTS"
 echo "*****************************************************************"
@@ -151,6 +155,11 @@ validateAndPrepareArtefacts() {
     cp "${SMP_ARTEFACTS}/smp-${SMP_VERSION}-setup.zip" ./tomcat-mysql-smp-sml/artefacts/smp-setup.zip
   fi
 
+  if [[ ! -f "${SMP_PLUGIN_EXAMPLE}" ]]; then
+    echo "SMP SPI plugin  '${SMP_PLUGIN_EXAMPLE}' not found. Skip plugin!"
+  else
+    cp "${SMP_PLUGIN_EXAMPLE}" ./tomcat-mysql-smp-sml/artefacts/smp-spi-example.jar
+  fi
 }
 
 # -----------------------------------------------------------------------------
diff --git a/smp-docker/images/tomcat-mysql-smp-sml/Dockerfile b/smp-docker/images/tomcat-mysql-smp-sml/Dockerfile
index 133ff6156030ece7c9b2be9571312825ae7f4a22..2429ef129fb6adb0864623d60c1174bab42b1d41 100755
--- a/smp-docker/images/tomcat-mysql-smp-sml/Dockerfile
+++ b/smp-docker/images/tomcat-mysql-smp-sml/Dockerfile
@@ -132,6 +132,8 @@ RUN unzip /tmp/artefacts/smp-setup.zip -d /tmp/    \
     && mv /tmp/bdmsl-webapp-$SML_VERSION /tmp/sml-setup \
     && cp /tmp/sml-setup/encriptionPrivateKey.private  /opt/smlconf/encriptionPrivateKey.private \
     && cp /tmp/sml-setup/keystore.jks /opt/smlconf/keystore.jk \
+    && mkdir $SMP_HOME/apache-tomcat-$TOMCAT_VERSION/smp-libs \
+    && mv /tmp/artefacts/*.jar $SMP_HOME/apache-tomcat-$TOMCAT_VERSION/smp-libs \
     && chmod u+x /sbin/entrypoint.sh
 
 
diff --git a/smp-docker/images/tomcat-mysql-smp-sml/README.md b/smp-docker/images/tomcat-mysql-smp-sml/README.md
index b923fd6fabf1b3f47aeff8b31cc1bf39a9fecf6f..0db205978ed894a3718c1cd623fa120560297467 100755
--- a/smp-docker/images/tomcat-mysql-smp-sml/README.md
+++ b/smp-docker/images/tomcat-mysql-smp-sml/README.md
@@ -4,12 +4,15 @@ Image uses latest version of eDelivery SMP setup on tomcat, mysql ubuntu
 
 # Image build
 
-docker build -t smp .
+    docker build -t smp .
 
 # Run container based on smp image
-docker run --name smp -it --rm -p [http-port]:8080 -v [local volume]:/data smp
+  
+    docker run --name smp -it --rm -p [http-port]:8080  edelivery-docker.devops.tech.ec.europa.eu/edeliverytest/smp-sml-tomcat-mysql
+
 example:
-docker run --name smp --rm -it -p 8080:8080 -v  /opt/dockerdata/smp:/data smp smp
+
+    docker run --name smp --rm -it -p 8080:8080  edelivery-docker.devops.tech.ec.europa.eu/edeliverytest/smp-sml-tomcat-mysql:4.2-SNAPSHOT
 
 ## SMP (param: -p 8080:8080 )
 url: http://localhost:8080/smp
@@ -20,9 +23,22 @@ url: jdbc:mysql://localhost:3306/smp
 Username: smp
 Password: smp
 
-## Volume (-v /opt/dockerdata/sml:/data)
+## Volume (-v /opt/docker-data/smp:/data)
 Mysql database files and tomcat configuration (and logs) can be externalized for experimenting with different SMP settings.
 
+    docker run --name smp --rm -it -p 8080:8080  -v /opt/docker-data/smp:/data edelivery-docker.devops.tech.ec.europa.eu/edeliverytest/smp-sml-tomcat-mysql:4.2-SNAPSHOT
+
+# Start docker with pre-init data  
+1. copy init sql script to folder (create folder)
+  
+    ./db-scripts
+
+example:
+        
+    curl -k https://ec.europa.eu/digital-building-blocks/code/projects/EDELIVERY/repos/smp/raw/smp-soapui-tests/groovy/mysql-4.1_integration_test_data.sql?at=refs%2Fheads%2Fdevelopment --output ./db-scripts/mysql5innodb-data.sql
+
+Then start the docker as:
 
+    docker run --name smp --rm -it -p 8080:8080  -v - db-scripts:/tmp/custom-data/ edelivery-docker.devops.tech.ec.europa.eu/edeliverytest/smp-sml-tomcat-mysql:4.2-SNAPSHOT 
 
 
diff --git a/smp-docker/images/tomcat-mysql-smp-sml/bind/db.test.edelivery.local b/smp-docker/images/tomcat-mysql-smp-sml/bind/db.test.edelivery.local
index 006d3d0cd818d01d1d96081b7b5ee735aa71f5c9..b962adfa8e4b5c0f42dbcaed90ac2a1fb53ce021 100755
--- a/smp-docker/images/tomcat-mysql-smp-sml/bind/db.test.edelivery.local
+++ b/smp-docker/images/tomcat-mysql-smp-sml/bind/db.test.edelivery.local
@@ -12,3 +12,4 @@ test.edelivery.local	IN SOA	ns.test.edelivery.local. root.test.edelivery.local.
 $ORIGIN test.edelivery.local.
 $TTL 60	; 1 minute
 ns			A	127.0.0.1
+CEF-SMP-002.publisher	60	IN	CNAME	localhost.
\ No newline at end of file
diff --git a/smp-docker/images/tomcat-mysql-smp-sml/entrypoint.sh b/smp-docker/images/tomcat-mysql-smp-sml/entrypoint.sh
index 7a4a0f4dee549332168dc06a38fbcae80f948e61..d3468905349ebf2f5828b63a6106f9725ebc3f93 100755
--- a/smp-docker/images/tomcat-mysql-smp-sml/entrypoint.sh
+++ b/smp-docker/images/tomcat-mysql-smp-sml/entrypoint.sh
@@ -83,6 +83,8 @@ init_smp_properties() {
     echo "[INFO] init smp properties:"
 
     { echo "# SMP init parameters"
+      echo "libraries.folder=$SMP_HOME/apache-tomcat-$TOMCAT_VERSION/smp-libs"
+      echo "bdmsl.integration.logical.address=${SMP_LOGICAL_ADDRESS:-http://localhost:8080/smp/}"
       echo "authentication.blueCoat.enabled=true"
       echo "bdmsl.integration.enabled=true"
       echo "bdmsl.integration.physical.address=0.0.0.0"
@@ -202,8 +204,8 @@ addOrReplaceProperties() {
     for property in "${array[@]}"; do
       read -r key value <<<"$property"
       # escape regex chars and remove trailing and leading spaces..
-      keyRE="$(printf '%s' "${key// }" | sed 's/[.[\*^$()+?{|]/\\&/g')"
-      propertyRE="$(printf '%s' "${property// }" | sed 's/[.[\*^$()+?{|/]/\\&/g')"
+      keyRE="$(printf '%s' "${key// }" | sed 's/[[\*^$()+?{|]/\\&/g')"
+      propertyRE="$(printf '%s' "${property// }" | sed 's/[[\*^$()+?{|/]/\\&/g')"
 
       echo "replace or add property: [$keyRE] with value [$propertyRE]"
       # replace key line and commented #key line with new property
diff --git a/smp-server-library/pom.xml b/smp-server-library/pom.xml
index 0006fd33f7f82c57e0bb6a2bf4ede8fc07aaef3f..ccd2e372b84723f4cab770388c4b9b2663d7ddbd 100644
--- a/smp-server-library/pom.xml
+++ b/smp-server-library/pom.xml
@@ -279,7 +279,7 @@
                                 2. script version
                                 3. export scripts.-->
                             <java classname="eu.europa.ec.edelivery.smp.data.dao.utils.SMPSchemaGenerator" fork="true" failonerror="true">
-                                <arg value="org.hibernate.dialect.Oracle10gDialect,org.hibernate.dialect.MySQL5InnoDBDialect" />
+                                <arg value="org.hibernate.dialect.Oracle10gDialect,org.hibernate.dialect.MySQL5InnoDBDialect,org.hibernate.dialect.H2Dialect" />
                                 <arg value="${project.version}" />
                                 <arg value="${project.basedir}/../smp-webapp/src/main/smp-setup/database-scripts" />
                                 <!-- reference to the passed-in classpath reference -->
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseConfig.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseConfig.java
index df10d4ba7b31abba588810b8fe02d1467e28b349..69ac211a866c86f4911d5e3e12dd74f1573f8a78 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseConfig.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseConfig.java
@@ -13,13 +13,10 @@
 
 package eu.europa.ec.edelivery.smp.config;
 
-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 eu.europa.ec.edelivery.smp.utils.ExtLibraryClassLoader;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
@@ -36,8 +33,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
 import javax.naming.NamingException;
 import javax.persistence.EntityManagerFactory;
 import javax.sql.DataSource;
-import java.io.File;
-import java.net.MalformedURLException;
 import java.util.Properties;
 
 import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.INTERNAL_ERROR;
@@ -74,7 +69,7 @@ public class DatabaseConfig {
     @Bean(name = "dataSource")
     public DataSource getDataSource() {
 
-        DataSource dataSource = null;
+        DataSource dataSource;
         if (!StringUtils.isBlank(url)) {
             LOG.info("create datasource with URL: " + url);
             DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseProperties.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseProperties.java
index b39f942c155aafa7ceee0e19b9deb27dfb58f68f..7331cfe880c0a35afd21a5798ae1fcfde1613419 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseProperties.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseProperties.java
@@ -4,6 +4,7 @@ import eu.europa.ec.edelivery.smp.data.model.DBConfiguration;
 import eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
+import eu.europa.ec.edelivery.smp.utils.PropertyUtils;
 
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
@@ -26,29 +27,14 @@ public class DatabaseProperties extends Properties {
         List<DBConfiguration> lst = tq.getResultList();
         for (DBConfiguration dc : lst) {
             if (dc.getValue() != null) {
-                LOG.info("Database property: [{}] value: [{}]", dc.getProperty(),
-                        isSensitiveData(dc.getProperty()) ? "******" : dc.getValue());
-                setProperty(trim(dc.getProperty()), trim(dc.getValue()));
+                String prop =trim(dc.getProperty());
+                String value =trim(dc.getValue());
+                setProperty(prop, value);
+                LOG.info("Database property: [{}] value: [{}]", prop,PropertyUtils.getMaskedData(prop, value) );
             }
             lastUpdate = (lastUpdate == null || lastUpdate.isBefore(dc.getLastUpdatedOn())) ? dc.getLastUpdatedOn() : lastUpdate;
         }
     }
-
-    /**
-     * Return true for properties which must not be logged!
-     *
-     * @param property - value to validate if contains sensitive data
-     * @return true if data is sensitive, else return false
-     */
-    public boolean isSensitiveData(String property) {
-        Optional<SMPPropertyEnum> propOpt = SMPPropertyEnum.getByProperty(property);
-        if (propOpt.isPresent()) {
-            return propOpt.get().isEncrypted() || property.toLowerCase().contains(".password.decrypted");
-        }
-        LOG.warn("Database property [{}] is not recognized by the SMP!", property);
-        return false;
-    }
-
     public OffsetDateTime getLastUpdate() {
         return lastUpdate;
     }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/FileProperty.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/FileProperty.java
index b10e90017a1c656b0e725f7a877a0646593da41a..ab78d7cbea3230cbe11cbee38f9a9d6b2db0a29c 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/FileProperty.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/FileProperty.java
@@ -23,6 +23,11 @@ public class FileProperty {
 
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(FileProperty.class);
 
+    // the property file is set in the root fo the resources
+    public static final String PROPERTY_FILE = "/smp.config.properties";
+    // legacy configuration file
+    public static final String PROPERTY_FILE_BACKUP = "/config.properties";
+
     public static final String PROPERTY_LOG_FOLDER = "log.folder";
     public static final String PROPERTY_LOG_PROPERTIES = "log.configuration.file";
     public static final String PROPERTY_DB_DRIVER = "jdbc.driver";
@@ -32,6 +37,7 @@ public class FileProperty {
     public static final String PROPERTY_DB_JNDI = "datasource.jndi";
     public static final String PROPERTY_DB_DIALECT = "hibernate.dialect";
     public static final String PROPERTY_LIB_FOLDER = "libraries.folder";
+    public static final String PROPERTY_SMP_MODE_DEVELOPMENT = "smp.mode.development";
 
     public static void updateLogConfiguration(String logFileFolder, String logPropertyFile, String configurationFolder) {
 
@@ -58,7 +64,7 @@ public class FileProperty {
 
     public static void setLogConfiguration(File configurationFile) {
         try (InputStream configStream = new FileInputStream(configurationFile)) {
-                LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+            LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
             JoranConfigurator configurator = new JoranConfigurator();
             configurator.setContext(context);
             configurator.doConfigure(configStream); // loads logback file
@@ -68,11 +74,15 @@ public class FileProperty {
     }
 
     public static Properties getFileProperties() {
-        LOG.info("Start read file properties from '/smp.config.properties'");
-        InputStream is = PropertyInitialization.class.getResourceAsStream("/smp.config.properties");
+        return getFileProperties(PROPERTY_FILE);
+    }
+
+    public static Properties getFileProperties(String filename) {
+        LOG.info("Start read file properties from [{}]", filename);
+        InputStream is = PropertyInitialization.class.getResourceAsStream(filename);
         if (is == null) {
-            LOG.info("File '/smp.config.properties' not found in classpath, read '/config.properties'");
-            is = PropertyInitialization.class.getResourceAsStream("/config.properties");
+            LOG.info("File '[{}]' not found in classpath, read [{}].", filename, PROPERTY_FILE_BACKUP);
+            is = PropertyInitialization.class.getResourceAsStream(PROPERTY_FILE_BACKUP);
         }
         Properties connectionProp = new Properties();
         try {
@@ -84,17 +94,19 @@ public class FileProperty {
         // update deprecated values and return properties:
         return updateDeprecatedValues(connectionProp);
     }
+
     /**
      * Method validates if new value for deprecated value is already set. If not it set the value from deprecated property if exists!
+     *
      * @param properties
      * @return
      */
-    public static Properties updateDeprecatedValues(Properties properties){
+    public static Properties updateDeprecatedValues(Properties properties) {
         if (!properties.containsKey(EXTERNAL_TLS_AUTHENTICATION_CLIENT_CERT_HEADER_ENABLED.getProperty())
-                && properties.containsKey(CLIENT_CERT_HEADER_ENABLED_DEPRECATED.getProperty())){
+                && properties.containsKey(CLIENT_CERT_HEADER_ENABLED_DEPRECATED.getProperty())) {
 
             properties.setProperty(EXTERNAL_TLS_AUTHENTICATION_CLIENT_CERT_HEADER_ENABLED.getProperty(),
-                    properties.getProperty(CLIENT_CERT_HEADER_ENABLED_DEPRECATED.getProperty()) );
+                    properties.getProperty(CLIENT_CERT_HEADER_ENABLED_DEPRECATED.getProperty()));
         }
 
         return properties;
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/PropertyInitialization.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/PropertyInitialization.java
index 0d00d807f735a5f88089ddb034dda911fcbe3a35..7b67cf97c5e45d33c4be2cd9dea0836039e0f39c 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/PropertyInitialization.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/PropertyInitialization.java
@@ -21,6 +21,7 @@ import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.utils.SecurityUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.springframework.jdbc.datasource.DriverManagerDataSource;
 import org.springframework.jndi.JndiObjectFactoryBean;
 import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
@@ -34,10 +35,8 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
 import java.util.Properties;
 
 import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.*;
@@ -62,25 +61,33 @@ public class PropertyInitialization {
     protected Properties getDatabaseProperties(Properties fileProperties) {
         String dialect = fileProperties.getProperty(FileProperty.PROPERTY_DB_DIALECT);
         if (StringUtils.isBlank(dialect)) {
-            LOG.warn("Attribute: {} is empty. Database might not initialize!", FileProperty.PROPERTY_DB_DIALECT);
+            LOG.warn("The application property: {} is not set!. Database might not initialize!", FileProperty.PROPERTY_DB_DIALECT);
         }
         // get datasource
         DataSource dataSource = getDatasource(fileProperties);
         EntityManager em = null;
-        DatabaseProperties prop = null;
+        DatabaseProperties prop;
+        boolean devMode = Boolean.parseBoolean(fileProperties.getProperty(FileProperty.PROPERTY_SMP_MODE_DEVELOPMENT, "false"));
+        if (devMode) {
+            LOG.warn("***********************************************************************");
+            LOG.warn("WARNING: The SMP is started in DEVELOPMENT mode!");
+            LOG.warn("***********************************************************************");
+        }
         try {
             em = createEntityManager(dataSource, dialect);
             prop = new DatabaseProperties(em);
             if (prop.size() == 0) {
-                initializeProperties(em, fileProperties, prop);
+                initializeProperties(em, fileProperties, prop, devMode);
             } else {
-                validateProperties(em, fileProperties, prop);
+                validateProperties(em, fileProperties, prop, devMode);
             }
         } finally {
             if (em != null && em.isOpen()) {
                 em.close();
             }
         }
+
+        prop.setProperty(FileProperty.PROPERTY_SMP_MODE_DEVELOPMENT, Boolean.toString(devMode));
         return prop;
     }
 
@@ -96,10 +103,10 @@ public class PropertyInitialization {
      * @param em
      * @param fileProperties
      */
-    protected void initializeProperties(EntityManager em, Properties fileProperties, Properties initProperties) {
+    protected void initializeProperties(EntityManager em, Properties fileProperties, Properties initProperties, boolean testMode) {
         em.getTransaction().begin();
         LOG.warn("Database configuration table is empty! Initialize new values!");
-        File encFile = initNewValues(em, fileProperties, initProperties);
+        File encFile = initNewValues(em, fileProperties, initProperties, testMode);
 
         for (SMPPropertyEnum val : SMPPropertyEnum.values()) {
             DBConfiguration dbConf = null;
@@ -133,11 +140,9 @@ public class PropertyInitialization {
         em.getTransaction().commit();
     }
 
-    public void initTruststore(String absolutePath, File fEncryption, EntityManager em, Properties properties, Properties fileProperties) {
+    public void initTruststore(String absolutePath, File fEncryption, EntityManager em, Properties properties, Properties fileProperties, boolean testMode) {
         LOG.info("Start generating new truststore.");
-
         String encTrustEncToken;
-
         if (fileProperties.containsKey(SMPPropertyEnum.TRUSTSTORE_PASSWORD.getProperty())) {
             LOG.info("get token from  properties");
             encTrustEncToken = SecurityUtils.encryptWrappedToken(fEncryption,
@@ -145,7 +150,7 @@ public class PropertyInitialization {
         } else {
             // generate new token
             LOG.info("generate  token");
-            String trustToken = SecurityUtils.generateAuthenticationToken();
+            String trustToken = SecurityUtils.generateAuthenticationToken(testMode);
             storeDBEntry(em, SMPPropertyEnum.TRUSTSTORE_PASSWORD_DECRYPTED, trustToken);
             encTrustEncToken = SecurityUtils.encrypt(fEncryption, trustToken);
         }
@@ -167,6 +172,7 @@ public class PropertyInitialization {
             LOG.info("Generate  truststore file ");
             truststore = getNewFile(absolutePath, "smp-truststore.jks");
         }
+        LOG.info("Generate new truststore to file [{}]!", truststore.getAbsolutePath());
         // store file to database 
         storeDBEntry(em, SMPPropertyEnum.TRUSTSTORE_FILENAME, truststore.getName());
         properties.setProperty(SMPPropertyEnum.TRUSTSTORE_FILENAME.getProperty(), truststore.getName());
@@ -180,25 +186,17 @@ public class PropertyInitialization {
                 // init the truststore
                 newTrustStore.load(null, trustToken.toCharArray());
                 newTrustStore.store(out, trustToken.toCharArray());
-            } catch (IOException e) {
-                throw new SMPRuntimeException(INTERNAL_ERROR, e, "IOException occurred while creating truststore", e.getMessage());
-            } catch (CertificateException e) {
-                throw new SMPRuntimeException(INTERNAL_ERROR, e, "CertificateException occurred while creating truststore", e.getMessage());
-            } catch (NoSuchAlgorithmException e) {
-                throw new SMPRuntimeException(INTERNAL_ERROR, e, "NoSuchAlgorithmException occurred while creating truststore", e.getMessage());
-            } catch (KeyStoreException e) {
-                throw new SMPRuntimeException(INTERNAL_ERROR, e, "KeyStoreException occurred while creating truststore", e.getMessage());
             } catch (Exception e) {
-                throw new SMPRuntimeException(INTERNAL_ERROR, e, "Exception occurred while creating truststore", e.getMessage());
+                throw new SMPRuntimeException(INTERNAL_ERROR, e, "Exception occurred while creating truststore", ExceptionUtils.getRootCauseMessage(e));
             }
         }
     }
 
     public void initAndMergeKeystore(String absolutePath, File fEncryption, EntityManager em, Properties initProperties,
-                                     Properties fileProperties) {
-
+                                     Properties fileProperties, boolean testMode) {
+        LOG.info("Start generating new keystore.");
         // store keystore password  filename
-        String newKeyPassword = SecurityUtils.generateAuthenticationToken();
+        String newKeyPassword = SecurityUtils.generateAuthenticationToken(testMode);
         storeDBEntry(em, SMPPropertyEnum.KEYSTORE_PASSWORD_DECRYPTED, newKeyPassword);
         String encPasswd = SecurityUtils.encrypt(fEncryption, newKeyPassword);
         storeDBEntry(em, SMPPropertyEnum.KEYSTORE_PASSWORD, encPasswd);
@@ -216,41 +214,34 @@ public class PropertyInitialization {
             // check if keystore is empty then generate cert for user
             if (newKeystore.size() == 0) {
                 X509CertificateUtils.createAndStoreCertificateWithChain(
-                        new String []{TEST_CERT_ISSUER_DN, TEST_CERT_SUBJECT_DN},
-                        new String []{TEST_CERT_ISSUER_ALIAS, TEST_CERT_CERT_ALIAS},
+                        new String[]{TEST_CERT_ISSUER_DN, TEST_CERT_SUBJECT_DN},
+                        new String[]{TEST_CERT_ISSUER_ALIAS, TEST_CERT_CERT_ALIAS},
                         newKeystore, newKeyPassword);
             }
             newKeystore.store(out, newKeyPassword.toCharArray());
-        } catch (IOException e) {
-            throw new SMPRuntimeException(INTERNAL_ERROR, e, "IOException occurred while creating keystore", e.getMessage());
-        } catch (CertificateException e) {
-            throw new SMPRuntimeException(INTERNAL_ERROR, e, "CertificateException occurred while creating keystore", e.getMessage());
-        } catch (NoSuchAlgorithmException e) {
-            throw new SMPRuntimeException(INTERNAL_ERROR, e, "NoSuchAlgorithmException occurred while creating keystore", e.getMessage());
-        } catch (KeyStoreException e) {
-            throw new SMPRuntimeException(INTERNAL_ERROR, e, "KeyStoreException occurred while creating keystore", e.getMessage());
         } catch (Exception e) {
-            throw new SMPRuntimeException(INTERNAL_ERROR, e, "Exception occurred while creating keystore", e.getMessage());
+            throw new SMPRuntimeException(INTERNAL_ERROR, e, "Exception occurred while creating keystore", ExceptionUtils.getRootCauseMessage(e));
         }
     }
 
     public File initEncryptionKey(String absolutePath, EntityManager em, Properties initProperties, Properties fileProperties) {
+        LOG.info("Calculate encryption key [{}]. This could take some time!", absolutePath);
         File fEncryption;
         if (fileProperties.containsKey(ENCRYPTION_FILENAME.getProperty())) {
             fEncryption = new File(absolutePath, fileProperties.getProperty(ENCRYPTION_FILENAME.getProperty()));
 
         } else {
-            fEncryption = getNewFile(absolutePath, SMPPropertyEnum.ENCRYPTION_FILENAME.getDefValue());
+            fEncryption = getNewFile(absolutePath, ENCRYPTION_FILENAME.getDefValue());
         }
-        ;
         // if file is not existing yet - as is the case in getNewFile create file
         if (!fEncryption.exists()) {
             SecurityUtils.generatePrivateSymmetricKey(fEncryption);
         }
 
         SecurityUtils.generatePrivateSymmetricKey(fEncryption);
-        storeDBEntry(em, SMPPropertyEnum.ENCRYPTION_FILENAME, fEncryption.getName());
-        initProperties.setProperty(SMPPropertyEnum.ENCRYPTION_FILENAME.getProperty(), fEncryption.getName());
+        LOG.info("Encryption key generated.");
+        storeDBEntry(em, ENCRYPTION_FILENAME, fEncryption.getName());
+        initProperties.setProperty(ENCRYPTION_FILENAME.getProperty(), fEncryption.getName());
         return fEncryption;
     }
 
@@ -260,34 +251,31 @@ public class PropertyInitialization {
      * @param em
      * @param fileProperties
      */
-    protected File initNewValues(EntityManager em, Properties fileProperties, Properties initProperties) {
+    protected File initNewValues(EntityManager em, Properties fileProperties, Properties initProperties, boolean testMode) {
         String absolutePath;
         if (fileProperties.containsKey(CONFIGURATION_DIR.getProperty())) {
             absolutePath = fileProperties.getProperty(CONFIGURATION_DIR.getProperty());
         } else {
-            File settingsFolder = new File("/");
             // set absolute path
-            absolutePath = new File("/").getAbsolutePath();
+            absolutePath = Paths.get(CONFIGURATION_DIR.getDefValue()).toFile().getAbsolutePath();
+            LOG.warn("The property [{}] Initialize SMP configuration files to folder [{}]!", CONFIGURATION_DIR.getProperty(), absolutePath);
         }
 
         File confFolder = new File(absolutePath);
         if (!confFolder.exists()) {
-            LOG.warn("Configuration folder {} not exists. Folder will be created!", confFolder.getAbsolutePath());
+            LOG.warn("Configuration folder [{}] not exists. Folder will be created!", confFolder.getAbsolutePath());
             confFolder.mkdirs();
         }
-
-        LOG.info("Generate new keystore to folder: " + absolutePath);
         // add configuration path
         storeDBEntry(em, CONFIGURATION_DIR, absolutePath);
         initProperties.setProperty(CONFIGURATION_DIR.getProperty(), absolutePath);
 
         // init encryption filename
-
         File fEncryption = initEncryptionKey(absolutePath, em, initProperties, fileProperties);
 
         // init truststore
-        initTruststore(absolutePath, fEncryption, em, initProperties, fileProperties);
-        initAndMergeKeystore(absolutePath, fEncryption, em, initProperties, fileProperties);
+        initTruststore(absolutePath, fEncryption, em, initProperties, fileProperties, testMode);
+        initAndMergeKeystore(absolutePath, fEncryption, em, initProperties, fileProperties, testMode);
 
         return fEncryption;
     }
@@ -323,7 +311,7 @@ public class PropertyInitialization {
      * @param em
      * @param fileProperties
      */
-    protected void validateProperties(EntityManager em, Properties fileProperties, Properties databaseProperties) {
+    protected void validateProperties(EntityManager em, Properties fileProperties, Properties databaseProperties, boolean devMode) {
         em.getTransaction().begin();
 
         if (!databaseProperties.containsKey(CONFIGURATION_DIR.getProperty())) {
@@ -353,7 +341,7 @@ public class PropertyInitialization {
 
         // init this one because it is new!
         if (!databaseProperties.containsKey(TRUSTSTORE_FILENAME.getProperty())) {
-            initTruststore(configurationDir, fEncryption, em, databaseProperties, fileProperties);
+            initTruststore(configurationDir, fEncryption, em, databaseProperties, fileProperties, devMode);
         }
         em.getTransaction().commit();
     }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/PropertyUpdateListener.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/PropertyUpdateListener.java
index 15e57c40372a94221e4baf52cbce2d238c8589e7..2e6914f930aca7bf90cfc56a8d53250d89c7f1a5 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/PropertyUpdateListener.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/PropertyUpdateListener.java
@@ -37,6 +37,4 @@ public interface PropertyUpdateListener {
     default void updateProperty(SMPPropertyEnum property, Object value) {
         updateProperties(Collections.singletonMap(property, value));
     }
-
-    ;
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDao.java
index 10db28feb0915cb50eeca54fad707c7637d8c42a..ca29a53265313adf8cbd4639032ff273d9ba21b8 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDao.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDao.java
@@ -27,6 +27,7 @@ import eu.europa.ec.edelivery.smp.utils.SecurityUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.springframework.context.ApplicationContext;
+import org.springframework.context.event.ContextRefreshedEvent;
 import org.springframework.context.event.ContextStartedEvent;
 import org.springframework.context.event.ContextStoppedEvent;
 import org.springframework.context.event.EventListener;
@@ -88,8 +89,8 @@ public class ConfigurationDao extends BaseDao<DBConfiguration> {
 
     @Transactional
     public DBConfiguration setPropertyToDatabase(SMPPropertyEnum key, String value, String description) {
-
-        if (!PropertyUtils.isValidProperty(key, value)) {
+        File rootFolder = (File)getCachedPropertyValue(CONFIGURATION_DIR);
+        if (!PropertyUtils.isValidProperty(key, value, rootFolder)) {
             throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, key.getPropertyType().getErrorMessage(key.getProperty()));
         }
 
@@ -143,11 +144,15 @@ public class ConfigurationDao extends BaseDao<DBConfiguration> {
     }
 
     public String getCachedProperty(SMPPropertyEnum key) {
+        return getCachedProperty(key.getProperty(), key.getDefValue());
+    }
+
+    public String getCachedProperty(String property,String defValue) {
         if (lastUpdate == null) {
             // init properties
             refreshProperties();
         }
-        return cachedProperties.getProperty(key.getProperty(), key.getDefValue());
+        return cachedProperties.getProperty(property, defValue);
     }
 
     public Object getCachedPropertyValue(SMPPropertyEnum key) {
@@ -217,7 +222,7 @@ public class ConfigurationDao extends BaseDao<DBConfiguration> {
     /**
      * Application event when an {@code ApplicationContext} gets initialized or start
      */
-    @EventListener({ContextStartedEvent.class})
+    @EventListener({ContextRefreshedEvent.class})
     public void contextRefreshedEvent() {
         LOG.debug("Application context is initialized: triggered  refresh  to update all property listeners");
         setInitializedTime(OffsetDateTime.now());
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/PropertyRO.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/PropertyRO.java
index 7e9ec1ac5ae887e2d992abd4a2a73a7d9608cddb..bd0bf59945f18a230a36a74cec4ace2088ebf8e9 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/PropertyRO.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/PropertyRO.java
@@ -14,11 +14,17 @@ public class PropertyRO extends BaseRO{
     String newValue;
     boolean mandatory;
     boolean restartNeeded;
+    String valuePattern;
 
-    public PropertyRO() {
+    public PropertyRO(){}
+
+    public PropertyRO(String property, String value) {
+        this.property = property;
+        this.value = value;
     }
 
     public PropertyRO(String property, String value, String type, String desc) {
+        this(property, value);
         this.property = property;
         this.value = value;
         this.type = type;
@@ -96,4 +102,12 @@ public class PropertyRO extends BaseRO{
     public void setRestartNeeded(boolean restartNeeded) {
         this.restartNeeded = restartNeeded;
     }
+
+    public String getValuePattern() {
+        return valuePattern;
+    }
+
+    public void setValuePattern(String valuePattern) {
+        this.valuePattern = valuePattern;
+    }
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/PropertyValidationRO.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/PropertyValidationRO.java
new file mode 100644
index 0000000000000000000000000000000000000000..02706d9c8df9b744159128a830ca4fb22e351e35
--- /dev/null
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/PropertyValidationRO.java
@@ -0,0 +1,45 @@
+package eu.europa.ec.edelivery.smp.data.ui;
+
+public class PropertyValidationRO {
+    public static final int ERROR_CODE_OK =0;
+    public static final int ERROR_CODE_SERVICE_GROUP_EXISTS =1;
+    public static final int ERROR_CODE_INVALID_EXTENSION =2;
+
+    String property;
+    String value;
+
+    boolean propertyValid;
+    String errorMessage;
+
+    public String getProperty() {
+        return property;
+    }
+
+    public void setProperty(String property) {
+        this.property = property;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public boolean isPropertyValid() {
+        return propertyValid;
+    }
+
+    public void setPropertyValid(boolean propertyValid) {
+        this.propertyValid = propertyValid;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(String errorMessage) {
+        this.errorMessage = errorMessage;
+    }
+}
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/ServiceResult.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/ServiceResult.java
index eaf5b034572032d4fb419e0cb070ff28724d49aa..1f88ef6524475ea437f0224ed8dfe829de93ff78 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/ServiceResult.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/ServiceResult.java
@@ -13,7 +13,7 @@ public class  ServiceResult<T> implements Serializable {
 
     private static final long serialVersionUID = -4971552086560325302L;
 
-    private Map<String, Object> filter; //NOSONAR
+    private String filter; //NOSONAR
     private List<T> serviceEntities; //NOSONAR
 
 
@@ -21,11 +21,11 @@ public class  ServiceResult<T> implements Serializable {
     private Integer page;
     private Integer pageSize;
 
-    public Map<String, Object> getFilter() {
+    public String getFilter() {
         return filter;
     }
 
-    public void setFilter(Map<String, Object> filter) {
+    public void setFilter(String filter) {
         this.filter = filter;
     }
 
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java
index 4176a2b645130b6fbc418f635660fab2e89f6482..aa31c92d0063db5f514df29e3d61780e9e7664b9 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java
@@ -79,7 +79,7 @@ public enum SMPPropertyEnum {
             "Force change password at UI login if expired", false, false,false, BOOLEAN),
 
     USER_LOGIN_FAIL_DELAY("smp.user.login.fail.delay","1000",
-            "Delay in ms on invalid username or password", false, false,false, INTEGER),
+            "Delay response in ms on invalid username or password", false, false,false, INTEGER),
 
     USER_MAX_FAILED_ATTEMPTS("smp.user.login.maximum.attempt","5",
             "Number of console login attempt before the user is deactivated", false, false,false, INTEGER),
@@ -117,7 +117,7 @@ public enum SMPPropertyEnum {
     SSO_CAS_TOKEN_VALIDATION_PARAMS("smp.sso.cas.token.validation.params", "acceptStrengths:BASIC,CLIENT_CERT|assuranceLevel:TOP", "The CAS token validation key:value properties separated with '|'.Ex: 'acceptStrengths:BASIC,CLIENT_CERT|assuranceLevel:TOP'", false, false, true, MAP_STRING),
     SSO_CAS_TOKEN_VALIDATION_GROUPS("smp.sso.cas.token.validation.groups", "DIGIT_SMP|DIGIT_ADMIN", "'|' separated CAS groups user must belong to.", false, false, true, LIST_STRING),
 
-    MAIL_SERVER_HOST("mail.smtp.host", "mail.server.com", "Email server - configuration for submitting the emails.", false,false, false, STRING),
+    MAIL_SERVER_HOST("mail.smtp.host", "", "Email server - configuration for submitting the emails.", false,false, false, STRING),
     MAIL_SERVER_PORT("mail.smtp.port", "25", "Smtp mail port - configuration for submitting the emails.", false,false, false,INTEGER),
     MAIL_SERVER_PROTOCOL("mail.smtp.protocol", "smtp", "smtp mail protocol- configuration for submitting the emails.", false,false,false, STRING),
     MAIL_SERVER_USERNAME("mail.smtp.username", "", "smtp mail protocol- username for submitting the emails.", false,false,false, STRING),
@@ -217,13 +217,14 @@ public enum SMPPropertyEnum {
     String property;
     String defValue;
     String desc;
+    String valuePattern;
 
     boolean isEncrypted;
     boolean isMandatory;
     boolean restartNeeded;
     SMPPropertyTypeEnum propertyType;
 
-    SMPPropertyEnum(String property, String defValue, String desc, boolean isMandatory, boolean isEncrypted, boolean restartNeeded, SMPPropertyTypeEnum propertyType) {
+    SMPPropertyEnum(String property, String defValue, String desc, boolean isMandatory, boolean isEncrypted, boolean restartNeeded, SMPPropertyTypeEnum propertyType,String valuePattern) {
         this.property = property;
         this.defValue = defValue;
         this.desc = desc;
@@ -231,6 +232,12 @@ public enum SMPPropertyEnum {
         this.isMandatory = isMandatory;
         this.restartNeeded = restartNeeded;
         this.propertyType = propertyType;
+        this.valuePattern = valuePattern;
+    }
+
+    SMPPropertyEnum(String property, String defValue, String desc, boolean isMandatory, boolean isEncrypted, boolean restartNeeded, SMPPropertyTypeEnum propertyType) {
+        this(property, defValue, desc, isMandatory, isEncrypted, restartNeeded, propertyType, propertyType.errorTemplate);
+
     }
 
     public String getProperty() {
@@ -272,6 +279,10 @@ public enum SMPPropertyEnum {
     public static List<SMPPropertyEnum> getRestartOnChangeProperties() {
         return Arrays.asList(values()).stream().filter(val -> val.isRestartNeeded()).collect(Collectors.toList());
     }
+
+    public String getValuePattern() {
+        return valuePattern;
+    }
 }
 
 
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyTypeEnum.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyTypeEnum.java
index 8e4bcae33663cb11fc38ce5b73e8ad74dac504dc..ad19834547a57755f863f1b9b44e465d49bd8e23 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyTypeEnum.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyTypeEnum.java
@@ -1,23 +1,26 @@
 package eu.europa.ec.edelivery.smp.data.ui.enums;
 
 public enum SMPPropertyTypeEnum {
-    STRING ("Property [%s] is not valid String type!"),
-    LIST_STRING("Property [%s] is not valid LIST_STRING type!"),
-    MAP_STRING("Property [%s] is not valid MAP_STRING type!"),
-    INTEGER("Property [%s] is not valid Integer!"),
-    BOOLEAN("Property [%s] is not valid Boolean type!"),
-    REGEXP("Property [%s] is not valid Regular Expression type!"),
-    CRON_EXPRESSION("Property [%s] is not valid Cron Expression type!"),
-    EMAIL("Property [%s] is not valid Email address type!"),
-    FILENAME("Property [%s] is not valid Filename type or it does not exists!"),
-    PATH("Property [%s] is not valid Path type or it does not exists!"),
-    URL("Property [%s] is not valid URL type or it does not exists!"),
+    STRING (".*","Property [%s] is not valid String type!"),
+    LIST_STRING(".*","Property [%s] is not valid LIST_STRING type!"),
+    MAP_STRING(".*","Property [%s] is not valid MAP_STRING type!"),
+    INTEGER("\\d*","Property [%s] is not valid Integer!"),
+    BOOLEAN("true|false","Property [%s] is not valid Boolean type!"),
+    REGEXP(".*", "Property [%s] is not valid Regular Expression type!"),
+    CRON_EXPRESSION(".*","Property [%s] is not valid Cron Expression type!"),
+    EMAIL(".*","Property [%s] is not valid Email address type!"),
+    FILENAME(".*","Property [%s] is not valid Filename type or it does not exists!"),
+    PATH(".*","Property [%s] is not valid Path type or it does not exists!"),
+    URL(".*","Property [%s] is not valid URL type or it does not exists!"),
     ;
 
     String errorTemplate;
+    String defValidationRegExp;
 
-    SMPPropertyTypeEnum(String errorTemplate) {
+    SMPPropertyTypeEnum(String defValidationRegExp, String errorTemplate ) {
+        this.defValidationRegExp = defValidationRegExp;
         this.errorTemplate =errorTemplate;
+
     }
 
     public String getErrorMessage(String property) {
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/AlertService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/AlertService.java
index b16650985cba19200d27657cfda209757b401e42..d53bc26bf938a0311ec5cef6ffe477d010ee70b7 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/AlertService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/AlertService.java
@@ -54,9 +54,9 @@ public class AlertService {
         AlertLevelEnum alertLevel = configurationService.getAlertBeforeExpirePasswordLevel();
         AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_IMMINENT_EXPIRATION;
 
-        alertCredentialExpiration(mailSubject, mailTo,
-                credentialType, credentialId, expiredOn,
-                alertLevel, alertType);
+        DBAlert alert = createAlert(mailSubject, mailTo, alertLevel, alertType);
+
+        alertCredentialExpiration(alert, credentialType, credentialId, expiredOn);
     }
 
     public void alertUsernamePasswordExpired(DBUser user) {
@@ -73,9 +73,9 @@ public class AlertService {
         AlertLevelEnum alertLevel = configurationService.getAlertExpiredPasswordLevel();
         AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_EXPIRED;
 
-        alertCredentialExpiration(mailSubject, mailTo,
-                credentialType, credentialId, expiredOn,
-                alertLevel, alertType);
+        DBAlert alert = createAlert(mailSubject, mailTo, alertLevel, alertType);
+
+        alertCredentialExpiration(alert, credentialType, credentialId, expiredOn);
     }
 
     public void alertBeforeAccessTokenExpire(DBUser user) {
@@ -94,9 +94,8 @@ public class AlertService {
         AlertLevelEnum alertLevel = configurationService.getAlertBeforeExpireAccessTokenLevel();
         AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_IMMINENT_EXPIRATION;
 
-        alertCredentialExpiration(mailSubject, mailTo,
-                credentialType, credentialId, expiredOn,
-                alertLevel, alertType);
+        DBAlert alert = createAlert(mailSubject, mailTo, alertLevel, alertType);
+        alertCredentialExpiration(alert, credentialType, credentialId, expiredOn);
     }
 
     public void alertAccessTokenExpired(DBUser user) {
@@ -115,17 +114,15 @@ public class AlertService {
         AlertLevelEnum alertLevel = configurationService.getAlertExpiredAccessTokenLevel();
         AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_EXPIRED;
 
-        alertCredentialExpiration(mailSubject, mailTo,
-                credentialType, credentialId, expiredOn,
-                alertLevel, alertType);
+        DBAlert alert = createAlert(mailSubject, mailTo, alertLevel, alertType);
+        alertCredentialExpiration(alert, credentialType, credentialId, expiredOn);
     }
 
 
     public void alertBeforeCertificateExpire(DBUser user) {
-        LOG.info("Alert Certificate [{}] for user [{}] is about to expire on [{}]",
+        LOG.info("Alert Certificate [{}] for user [{}] is about to expire",
                 user.getCertificate().getCertificateId(),
-                user.getUsername(),
-                ISO_LOCAL_DATE_TIME.format(user.getAccessTokenExpireOn()));
+                user.getUsername());
 
         String mailTo = user.getEmailAddress();
         CredentialTypeEnum credentialType = CredentialTypeEnum.CERTIFICATE;
@@ -137,16 +134,14 @@ public class AlertService {
         AlertLevelEnum alertLevel = configurationService.getAlertBeforeExpireCertificateLevel();
         AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_IMMINENT_EXPIRATION;
 
-        alertCredentialExpiration(mailSubject, mailTo,
-                credentialType, credentialId, expiredOn,
-                alertLevel, alertType);
+        DBAlert alert = createAlert(mailSubject, mailTo, alertLevel, alertType);
+        alertCredentialExpiration(alert, credentialType, credentialId, expiredOn);
     }
 
     public void alertCertificateExpired(DBUser user) {
-        LOG.info("Alert Certificate [{}] for user [{}] expired on [{}]",
+        LOG.info("Alert Certificate [{}] for user [{}] expired",
                 user.getCertificate().getCertificateId(),
-                user.getUsername(),
-                ISO_LOCAL_DATE_TIME.format(user.getAccessTokenExpireOn()));
+                user.getUsername());
 
         String mailTo = user.getEmailAddress();
         CredentialTypeEnum credentialType = CredentialTypeEnum.CERTIFICATE;
@@ -158,168 +153,184 @@ public class AlertService {
         AlertLevelEnum alertLevel = configurationService.getAlertExpiredCertificateLevel();
         AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_EXPIRED;
 
-        alertCredentialExpiration(mailSubject, mailTo,
-                credentialType, credentialId, expiredOn,
-                alertLevel, alertType);
-    }
-
-
-    public void alertCredentialExpiration(String mailSubject,
-                                          String mailTo,
-                                          CredentialTypeEnum credentialType,
-                                          String credentialId,
-                                          OffsetDateTime expirationDate,
-                                          AlertLevelEnum level,
-                                          AlertTypeEnum alertType) {
-
-        // create alert
-        OffsetDateTime reportDate = OffsetDateTime.now();
-        String serverName = HttpUtils.getServerAddress();
-
-        DBAlert alert = new DBAlert();
-        alert.setProcessed(false);
-        alert.setMailSubject(mailSubject);
-        alert.setMailTo(mailTo);
-        alert.setReportingTime(reportDate);
-        alert.setAlertType(alertType);
-        alert.setAlertLevel(level);
-        alert.addProperty(CredentialsExpirationProperties.CREDENTIAL_TYPE.name(), credentialType.name());
-        alert.addProperty(CredentialsExpirationProperties.CREDENTIAL_ID.name(), credentialId);
-        alert.addProperty(CredentialsExpirationProperties.EXPIRATION_DATETIME.name(), expirationDate);
-        alert.addProperty(CredentialsExpirationProperties.REPORTING_DATETIME.name(), reportDate);
-        alert.addProperty(CredentialsExpirationProperties.ALERT_LEVEL.name(), level.name());
-        alert.addProperty(CredentialsExpirationProperties.SERVER_NAME.name(), serverName);
-        alertDao.persistFlushDetach(alert);
-        // submit alerts
-        submitAlertMail(alert);
-    }
-
-    public void submitAlertMail(DBAlert alert) {
-        String mailTo = alert.getMailTo();
-        if (StringUtils.isBlank(mailTo)) {
-            LOG.warn("Can not send mail (empty mail) for alert [{}]!", alert);
-            return;
-        }
-
-        String mailFrom = configurationService.getAlertEmailFrom();
-        PropertiesMailModel props = new PropertiesMailModel(alert);
-        mailService.sendMail(props, mailFrom, alert.getMailTo());
-
-        alert.setProcessed(true);
-        alert.setProcessedTime(OffsetDateTime.now());
-        alertDao.update(alert);
+        DBAlert alert = createAlert(mailSubject, mailTo, alertLevel, alertType);
+        alertCredentialExpiration(alert, credentialType, credentialId, expiredOn);
     }
 
-    public void alertCredentialVerificationFailed(DBUser user,CredentialTypeEnum credentialType) {
+    public void alertCredentialVerificationFailed(DBUser user, CredentialTypeEnum credentialType) {
         Boolean loginFailureEnabled = configurationService.getAlertUserLoginFailureEnabled();
         if (!loginFailureEnabled) {
-            LOG.debug("Alert Login failure is disabled!" );
+            LOG.debug("Alert Login failure is disabled!");
             return;
         }
 
         String mailTo = user.getEmailAddress();
-        String mailSubject = configurationService.getAlertBeforeUserSuspendedSubject();
-        AlertLevelEnum level = configurationService.getAlertUserSuspendedLevel();
+        String mailSubject = configurationService.getAlertUserLoginFailureSubject();
+        AlertLevelEnum alertLevel = configurationService.getAlertUserLoginFailureLevel();
         AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_VERIFICATION_FAILED;
-        Integer failureCount = user.getSequentialLoginFailureCount();
-        OffsetDateTime lastFailedLoginDate = user.getLastFailedLoginAttempt();
-        String credentialId = user.getUsername();
 
-        alertCredentialVerificationFailed(mailSubject, mailTo,
+        Integer failureCount;
+        OffsetDateTime lastFailedLoginDate;
+        String credentialId;
+
+        if(credentialType == CredentialTypeEnum.ACCESS_TOKEN) {
+            failureCount = user.getSequentialTokenLoginFailureCount();
+            lastFailedLoginDate = user.getLastTokenFailedLoginAttempt();
+            credentialId = user.getAccessTokenIdentifier();
+        }else if(credentialType == CredentialTypeEnum.USERNAME_PASSWORD) {
+            failureCount = user.getSequentialLoginFailureCount();
+            lastFailedLoginDate = user.getLastFailedLoginAttempt();
+            credentialId = user.getUsername();
+        } else {
+            LOG.error("Alert for suspended credentials type [{}] is not supported", credentialType);
+            return;
+        }
+        DBAlert alert = createAlert(mailSubject, mailTo, alertLevel, alertType);
+        alertCredentialVerificationFailed(alert,
                 credentialType, credentialId,
-                failureCount, lastFailedLoginDate,
-                level, alertType);
+                failureCount, lastFailedLoginDate);
     }
 
     public void alertCredentialsSuspended(DBUser user, CredentialTypeEnum credentialType) {
         Boolean suspensionAlertEnabled = configurationService.getAlertUserSuspendedEnabled();
         if (!suspensionAlertEnabled) {
-            LOG.debug("Alert suspended is disabled!" );
+            LOG.debug("Alert suspended is disabled!");
             return;
         }
 
         String mailTo = user.getEmailAddress();
-        String mailSubject = configurationService.getAlertBeforeUserSuspendedSubject();
-        AlertLevelEnum level = configurationService.getAlertUserSuspendedLevel();
+        String mailSubject = configurationService.getAlertUserSuspendedSubject();
+        AlertLevelEnum alertLevel = configurationService.getAlertUserSuspendedLevel();
         AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_SUSPENDED;
-        Integer failureCount = user.getSequentialLoginFailureCount();
-        OffsetDateTime lastFailedLoginDate = user.getLastFailedLoginAttempt();
-        OffsetDateTime suspendedUtil = lastFailedLoginDate.plusSeconds(configurationService.getLoginSuspensionTimeInSeconds());
-        String credentialId = user.getUsername();
 
-        alertCredentialSuspended(mailSubject, mailTo,
+        Integer failureCount;
+        OffsetDateTime lastFailedLoginDate;
+        OffsetDateTime suspendedUtil;
+        String credentialId;
+        if(credentialType == CredentialTypeEnum.ACCESS_TOKEN) {
+            failureCount = user.getSequentialTokenLoginFailureCount();
+            lastFailedLoginDate = user.getLastTokenFailedLoginAttempt();
+            suspendedUtil = lastFailedLoginDate.plusSeconds(configurationService.getAccessTokenLoginSuspensionTimeInSeconds());
+            credentialId = user.getAccessTokenIdentifier();
+        }else if(credentialType == CredentialTypeEnum.USERNAME_PASSWORD) {
+            failureCount = user.getSequentialLoginFailureCount();
+            lastFailedLoginDate = user.getLastFailedLoginAttempt();
+            suspendedUtil = lastFailedLoginDate.plusSeconds(configurationService.getLoginSuspensionTimeInSeconds());
+            credentialId = user.getUsername();
+        } else {
+            LOG.error("Alert for suspended credentials type [{}] is not supported", credentialType);
+            return;
+        }
+        DBAlert alert = createAlert(mailSubject, mailTo, alertLevel, alertType);
+
+        alertCredentialSuspended(alert,
                 credentialType, credentialId,
-                failureCount, lastFailedLoginDate, suspendedUtil,
-                level, alertType);
+                failureCount, lastFailedLoginDate, suspendedUtil);
     }
 
-    public void alertCredentialVerificationFailed(String mailSubject,
-                                         String mailTo,
-                                         CredentialTypeEnum credentialType,
-                                         String credentialId,
-                                         Integer failedLoginCount,
-                                         OffsetDateTime lastFailedLoginDate,
-                                         AlertLevelEnum level,
-                                         AlertTypeEnum alertType) {
-
-        Boolean suspensionAlertEnabled = configurationService.getAlertUserLoginFailureEnabled();
-        if (!suspensionAlertEnabled) {
-            LOG.debug("Alert suspended is disabled!" );
-            return;
-        }
+    public void alertCredentialExpiration(DBAlert alert,
+                                          CredentialTypeEnum credentialType,
+                                          String credentialId,
+                                          OffsetDateTime expirationDate
+                                          ) {
 
-        OffsetDateTime reportDate = OffsetDateTime.now();
         String serverName = HttpUtils.getServerAddress();
+        // add alert properties
+        alert.addProperty(CredentialsExpirationProperties.CREDENTIAL_TYPE.name(), credentialType.name());
+        alert.addProperty(CredentialsExpirationProperties.CREDENTIAL_ID.name(), credentialId);
+        alert.addProperty(CredentialsExpirationProperties.EXPIRATION_DATETIME.name(), expirationDate);
+        alert.addProperty(CredentialsExpirationProperties.REPORTING_DATETIME.name(), alert.getReportingTime());
+        alert.addProperty(CredentialsExpirationProperties.ALERT_LEVEL.name(), alert.getAlertLevel().name());
+        alert.addProperty(CredentialsExpirationProperties.SERVER_NAME.name(), serverName);
+        alertDao.persistFlushDetach(alert);
+        // submit alerts
+        submitAlertMail(alert);
+    }
 
-        DBAlert alert = new DBAlert();
-        alert.setProcessed(false);
-        alert.setMailSubject(mailSubject);
-        alert.setMailTo(mailTo);
-        alert.setReportingTime(reportDate);
-        alert.setAlertType(alertType);
-        alert.setAlertLevel(level);
+    public void alertCredentialVerificationFailed(DBAlert alert,
+                                                  CredentialTypeEnum credentialType,
+                                                  String credentialId,
+                                                  Integer failedLoginCount,
+                                                  OffsetDateTime lastFailedLoginDate
+                                                  ) {
+        String serverName = HttpUtils.getServerAddress();
+        // add alert properties
         alert.addProperty(CredentialVerificationFailedProperties.CREDENTIAL_TYPE.name(), credentialType.name());
         alert.addProperty(CredentialVerificationFailedProperties.CREDENTIAL_ID.name(), credentialId);
         alert.addProperty(CredentialVerificationFailedProperties.FAILED_LOGIN_ATTEMPT.name(), failedLoginCount.toString());
         alert.addProperty(CredentialVerificationFailedProperties.LAST_LOGIN_FAILURE_DATETIME.name(), lastFailedLoginDate);
-        alert.addProperty(CredentialVerificationFailedProperties.REPORTING_DATETIME.name(), reportDate);
-        alert.addProperty(CredentialVerificationFailedProperties.ALERT_LEVEL.name(), level.name());
+        alert.addProperty(CredentialVerificationFailedProperties.REPORTING_DATETIME.name(), alert.getReportingTime());
+        alert.addProperty(CredentialVerificationFailedProperties.ALERT_LEVEL.name(), alert.getAlertLevel().name());
         alert.addProperty(CredentialVerificationFailedProperties.SERVER_NAME.name(), serverName);
         alertDao.persistFlushDetach(alert);
         // submit alerts
         submitAlertMail(alert);
     }
-    public void alertCredentialSuspended(String mailSubject,
-                                         String mailTo,
+
+    public void alertCredentialSuspended(DBAlert alert,
                                          CredentialTypeEnum credentialType,
                                          String credentialId,
                                          Integer failedLoginCount,
                                          OffsetDateTime lastFailedLoginDate,
-                                         OffsetDateTime suspendedUtil,
-                                         AlertLevelEnum level,
-                                         AlertTypeEnum alertType) {
+                                         OffsetDateTime suspendedUtil) {
 
-        OffsetDateTime reportDate = OffsetDateTime.now();
         String serverName = HttpUtils.getServerAddress();
-
-        DBAlert alert = new DBAlert();
-        alert.setProcessed(false);
-        alert.setMailSubject(mailSubject);
-        alert.setMailTo(mailTo);
-        alert.setReportingTime(reportDate);
-        alert.setAlertType(alertType);
-        alert.setAlertLevel(level);
+        // add alert properties
         alert.addProperty(CredentialSuspendedProperties.CREDENTIAL_TYPE.name(), credentialType.name());
         alert.addProperty(CredentialSuspendedProperties.CREDENTIAL_ID.name(), credentialId);
         alert.addProperty(CredentialSuspendedProperties.FAILED_LOGIN_ATTEMPT.name(), failedLoginCount.toString());
         alert.addProperty(CredentialSuspendedProperties.LAST_LOGIN_FAILURE_DATETIME.name(), lastFailedLoginDate);
         alert.addProperty(CredentialSuspendedProperties.SUSPENDED_UNTIL_DATETIME.name(), suspendedUtil);
-        alert.addProperty(CredentialSuspendedProperties.REPORTING_DATETIME.name(), reportDate);
-        alert.addProperty(CredentialSuspendedProperties.ALERT_LEVEL.name(), level.name());
+        alert.addProperty(CredentialSuspendedProperties.REPORTING_DATETIME.name(), alert.getReportingTime());
+        alert.addProperty(CredentialSuspendedProperties.ALERT_LEVEL.name(), alert.getAlertLevel().name());
         alert.addProperty(CredentialSuspendedProperties.SERVER_NAME.name(), serverName);
         alertDao.persistFlushDetach(alert);
         // submit alerts
         submitAlertMail(alert);
     }
 
+    /**
+     *  Create Alert DB entity
+     *
+     * @param mailSubject
+     * @param mailTo
+     * @param level
+     * @param alertType
+     * @return
+     */
+    protected DBAlert createAlert(String mailSubject,
+                                String mailTo,
+                                AlertLevelEnum level,
+                                AlertTypeEnum alertType) {
+
+        DBAlert alert = new DBAlert();
+        alert.setProcessed(false);
+        alert.setMailSubject(mailSubject);
+        alert.setMailTo(mailTo);
+        alert.setReportingTime(OffsetDateTime.now());
+        alert.setAlertType(alertType);
+        alert.setAlertLevel(level);
+        return alert;
+    }
+
+    /**
+     * Submit mail  for the alert
+     * @param alert
+     */
+    public void submitAlertMail(DBAlert alert) {
+        String mailTo = alert.getMailTo();
+        if (StringUtils.isBlank(mailTo)) {
+            LOG.warn("Can not send mail (empty mail) for alert [{}]!", alert);
+            return;
+        }
+
+        String mailFrom = configurationService.getAlertEmailFrom();
+        PropertiesMailModel props = new PropertiesMailModel(alert);
+        mailService.sendMail(props, mailFrom, alert.getMailTo());
+
+        alert.setProcessed(true);
+        alert.setProcessedTime(OffsetDateTime.now());
+        alertDao.update(alert);
+    }
+
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java
index 3d26225b4c5849a49a709bf23fb5055d357b00c9..c923ac99035bf6bbe25dd3328f2276cac3f7fc44 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java
@@ -1,6 +1,7 @@
 package eu.europa.ec.edelivery.smp.services;
 
 import eu.europa.ec.edelivery.smp.auth.enums.SMPUserAuthenticationTypes;
+import eu.europa.ec.edelivery.smp.config.FileProperty;
 import eu.europa.ec.edelivery.smp.data.dao.ConfigurationDao;
 import eu.europa.ec.edelivery.smp.data.ui.enums.AlertLevelEnum;
 import eu.europa.ec.edelivery.smp.data.ui.enums.AlertSuspensionMomentEnum;
@@ -85,8 +86,8 @@ public class ConfigurationService {
     }
 
     public Integer getLoginFailDelayInMilliSeconds() {
-        Integer delay =(Integer) configurationDAO.getCachedPropertyValue(USER_LOGIN_FAIL_DELAY);
-        return delay==null? 1000:delay;
+        Integer delay = (Integer) configurationDAO.getCachedPropertyValue(USER_LOGIN_FAIL_DELAY);
+        return delay == null ? 1000 : delay;
     }
 
     public Integer getAccessTokenLoginMaxAttempts() {
@@ -98,8 +99,8 @@ public class ConfigurationService {
     }
 
     public Integer getAccessTokenLoginFailDelayInMilliSeconds() {
-        Integer delay =(Integer) configurationDAO.getCachedPropertyValue(ACCESS_TOKEN_FAIL_DELAY);
-        return delay==null? 1000:delay;
+        Integer delay = (Integer) configurationDAO.getCachedPropertyValue(ACCESS_TOKEN_FAIL_DELAY);
+        return delay == null ? 1000 : delay;
     }
 
     public Integer getHttpHeaderHstsMaxAge() {
@@ -336,7 +337,7 @@ public class ConfigurationService {
         return AlertLevelEnum.valueOf(level);
     }
 
-    public String getAlertBeforeUserLoginFailureSubject() {
+    public String getAlertUserLoginFailureSubject() {
         return (String) configurationDAO.getCachedPropertyValue(ALERT_USER_LOGIN_FAILURE_MAIL_SUBJECT);
     }
 
@@ -351,7 +352,7 @@ public class ConfigurationService {
         return AlertLevelEnum.valueOf(level);
     }
 
-    public String getAlertBeforeUserSuspendedSubject() {
+    public String getAlertUserSuspendedSubject() {
         return (String) configurationDAO.getCachedPropertyValue(ALERT_USER_SUSPENDED_MAIL_SUBJECT);
     }
 
@@ -504,5 +505,13 @@ public class ConfigurationService {
         return (String) configurationDAO.getCachedPropertyValue(SMP_ALERT_MAIL_FROM);
     }
 
+    /**
+     * Property is set in "file property configuration and can not be changed via database!
+     * @return true if smp server is started in development mode
+     */
+    public boolean isSMPStartupInDevMode() {
+        return Boolean.parseBoolean(configurationDAO.getCachedProperty(FileProperty.PROPERTY_SMP_MODE_DEVELOPMENT, "false"));
+    }
+
 
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/CredentialValidatorService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/CredentialValidatorService.java
index cac8e963afe81a2d479305f263f9c2d2283f5812..a67b37d9aef513c86b75ef84d570cd410224c1aa 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/CredentialValidatorService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/CredentialValidatorService.java
@@ -67,7 +67,7 @@ public class CredentialValidatorService {
     }
 
     protected void validateCredentialsForExpiredUsernames() {
-        Boolean alertExpired = configurationService.getAlertBeforeExpirePasswordEnabled();
+        Boolean alertExpired = configurationService.getAlertExpiredPasswordEnabled();
         if (alertExpired == null || !alertExpired) {
             LOG.debug("Expire user password validation is disabled");
             return;
@@ -94,7 +94,7 @@ public class CredentialValidatorService {
     }
 
     protected void validateCredentialsForExpiredAccessToken() {
-        Boolean alertExpired = configurationService.getAlertBeforeExpireAccessTokenEnabled();
+        Boolean alertExpired = configurationService.getAlertExpiredAccessTokenEnabled();
         if (alertExpired == null || !alertExpired) {
             LOG.debug("Expire user AccessToken validation is disabled");
             return;
@@ -122,7 +122,7 @@ public class CredentialValidatorService {
     }
 
     protected void validateCredentialsForExpiredCertificate() {
-        Boolean alertExpired = configurationService.getAlertBeforeExpireCertificateEnabled();
+        Boolean alertExpired = configurationService.getAlertExpiredCertificateEnabled();
         if (alertExpired == null || !alertExpired) {
             LOG.debug("Expire user Certificate validation is disabled");
             return;
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/DomainService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/DomainService.java
index 07e3aa15dd237fe399b3171a1929f324c6451074..952eb5346373619ec4bb502116e588fb7f99fd24 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/DomainService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/DomainService.java
@@ -54,7 +54,7 @@ public class DomainService {
 
 
     /**
-     * Method checks if domain is in right format. Domain must contains only alphanomeric chars and it shoud
+     * Method checks if domain is in right format. Domain must contains only alphanomeric chars and it must
      * not be longer than 50 chars.
      *
      * @param domain
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/PayloadValidatorService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/PayloadValidatorService.java
index 17dc306ec188686f8635e42f6afd03646db1f673..239509e48bcd593037e5535327c4fe95f61dce41 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/PayloadValidatorService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/PayloadValidatorService.java
@@ -53,7 +53,4 @@ public class PayloadValidatorService {
             throw new SMPRuntimeException(ErrorCode.INVALID_REQUEST, "Content validation failed", ExceptionUtils.getRootCauseMessage(e),e);
         }
     }
-
-    ;
-
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIPropertyService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIPropertyService.java
index 0ba7dcdffd51b6d47cb845e475bea1e5ecb65666..f200b8798882aba05701fbfac5cde706e65b2bf2 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIPropertyService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIPropertyService.java
@@ -4,22 +4,26 @@ import eu.europa.ec.edelivery.smp.cron.SMPDynamicCronTrigger;
 import eu.europa.ec.edelivery.smp.data.dao.ConfigurationDao;
 import eu.europa.ec.edelivery.smp.data.model.DBConfiguration;
 import eu.europa.ec.edelivery.smp.data.ui.PropertyRO;
+import eu.europa.ec.edelivery.smp.data.ui.PropertyValidationRO;
 import eu.europa.ec.edelivery.smp.data.ui.ServiceResultProperties;
 import eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum;
+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 eu.europa.ec.edelivery.smp.utils.PropertyUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestBody;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
+import java.io.File;
+import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import static eu.europa.ec.edelivery.smp.cron.CronTriggerConfig.TRIGGER_BEAN_PROPERTY_REFRESH;
+import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.CONFIGURATION_DIR;
 import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.SMP_CLUSTER_ENABLED;
 import static org.apache.commons.lang3.time.DateFormatUtils.ISO_8601_EXTENDED_DATETIME_FORMAT;
 
@@ -66,8 +70,8 @@ public class UIPropertyService {
                 .collect(Collectors.toMap(DBConfiguration::getProperty, Function.identity()));
 
         List<PropertyRO> properties = filteredProperties.stream()
-                .skip( page * (long)pageSize)
-                .limit(pageSize)
+                .skip( page<0?0:page * (long)pageSize)
+                .limit(pageSize<0?SMPPropertyEnum.values().length:pageSize)
                 .map(prop -> createProperty(prop, changedProps))
                 .collect(Collectors.toList());
 
@@ -76,11 +80,13 @@ public class UIPropertyService {
         result.setCount((long) filteredProperties.size());
         result.setPage(page);
         result.setPageSize(pageSize);
+        result.setFilter(filterByProperty);
         result.setServerRestartNeeded(configurationDao.isServerRestartNeeded());
         return result;
     }
 
     public PropertyRO createProperty(SMPPropertyEnum propertyType, Map<String, DBConfiguration> changedProps) {
+
         PropertyRO property = new PropertyRO(propertyType.getProperty(),
                 configurationDao.getCachedProperty(propertyType),
                 propertyType.getPropertyType().name(),
@@ -89,6 +95,7 @@ public class UIPropertyService {
         property.setEncrypted(propertyType.isEncrypted());
         property.setRestartNeeded(propertyType.isRestartNeeded());
         property.setMandatory(propertyType.isMandatory());
+        property.setValuePattern(property.getValuePattern());
 
         if (changedProps.containsKey(property.getProperty())) {
             property.setNewValue(changedProps.get(propertyType.getProperty()).getValue());
@@ -110,4 +117,38 @@ public class UIPropertyService {
         }
         configurationDao.reloadPropertiesFromDatabase();
     }
+
+    public PropertyValidationRO validateProperty(PropertyRO propertyRO) {
+        LOG.info("Validate property: [{}]", propertyRO.getProperty());
+        PropertyValidationRO propertyValidationRO = new PropertyValidationRO();
+        propertyValidationRO.setProperty(propertyRO.getProperty());
+        propertyValidationRO.setValue(propertyRO.getValue());
+
+        Optional<SMPPropertyEnum> optPropertyEnum = SMPPropertyEnum.getByProperty(propertyRO.getProperty());
+        if (!optPropertyEnum.isPresent()) {
+            LOG.debug("Property: [{}] is not SMP property!", propertyRO.getProperty());
+            propertyValidationRO.setErrorMessage("Property [" + propertyRO.getProperty() + "] is not SMP property!");
+            propertyValidationRO.setPropertyValid(false);
+            return propertyValidationRO;
+        }
+        SMPPropertyEnum propertyEnum = optPropertyEnum.get();
+        if (StringUtils.isBlank(propertyRO.getValue()) && propertyEnum.isMandatory()) {
+            propertyValidationRO.setErrorMessage("Property [" + propertyRO.getProperty() + "] must not be NULL OR empty!");
+            propertyValidationRO.setPropertyValid(false);
+            return propertyValidationRO;
+        }
+
+        // try to parse value
+        try {
+            File confDir = (File) configurationDao.getCachedPropertyValue(CONFIGURATION_DIR);
+            PropertyUtils.parseProperty(propertyEnum, propertyRO.getValue(), confDir);
+        } catch (SMPRuntimeException ex) {
+            propertyValidationRO.setErrorMessage(ex.getMessage());
+            propertyValidationRO.setPropertyValid(false);
+            return propertyValidationRO;
+        }
+
+        propertyValidationRO.setPropertyValid(true);
+        return propertyValidationRO;
+    }
 }
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 88e757865730f24520b568f2969928194d0f7b41..29debdc146a9adc8c2cf825f25f7068b018c1f16 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
@@ -116,14 +116,15 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
         if (!BCrypt.checkpw(currentPassword, dbUser.getPassword())) {
             throw new BadCredentialsException("Password change failed; Invalid current password!");
         }
-        // setup new daes
-        AccessTokenRO token = SecurityUtils.generateAccessToken();
+        Boolean testMode = configurationService.isSMPStartupInDevMode();
+        AccessTokenRO token = SecurityUtils.generateAccessToken(testMode);
         OffsetDateTime generatedTime = token.getGeneratedOn();
         token.setExpireOn(generatedTime.plusDays(configurationService.getAccessTokenPolicyValidDays()));
         dbUser.setAccessTokenIdentifier(token.getIdentifier());
         dbUser.setAccessToken(BCryptPasswordHash.hashPassword(token.getValue()));
         dbUser.setAccessTokenGeneratedOn(generatedTime);
-        dbUser.setPasswordExpireOn(token.getExpireOn());
+        dbUser.setAccessTokenExpireOn(token.getExpireOn());
+
         return token;
     }
 
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/sml/SmlConnector.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/sml/SmlConnector.java
index 403a0e5880c9475cbda4e062a9250dd659957aff..8e8cbcc3f5fe276c5729bf138adbfd0f597faa11 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/sml/SmlConnector.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/sml/SmlConnector.java
@@ -362,6 +362,7 @@ public class SmlConnector implements ApplicationContextAware {
         tlsParams.setUseHttpsURLConnectionDefaultHostnameVerifier(false);
         tlsParams.setCertConstraints(createCertConstraint(configurationService.getSMLIntegrationServerCertSubjectRegExpPattern()));
         tlsParams.setDisableCNCheck(configurationService.smlDisableCNCheck());
+        tlsParams.setTrustManagers(truststoreService.getTrustManagers());
 
         if (!clientCertAuthentication) {
             LOG.info("SML X509 certificate authentication with alias  {}.", smlClientAuthentication);
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/ExtLibraryClassLoader.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/ExtLibraryClassLoader.java
index faaeb1dba3c29516937994f282ab2ef6c465fcbc..8d4ac7eae932c563f6ea6cf0e6e7221566325d10 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/ExtLibraryClassLoader.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/ExtLibraryClassLoader.java
@@ -1,6 +1,5 @@
 package eu.europa.ec.edelivery.smp.utils;
 
-import com.google.common.collect.Lists;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 
@@ -9,14 +8,15 @@ import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.util.*;
+import java.util.Arrays;
+import java.util.List;
 import java.util.stream.Collectors;
 
 /**
  * @author Cosmin Baciu
  * @author Joze Rihtarsic
  * @since 4.2
- *
+ * <p>
  * ExtLibraryClassLoader extends URLClassLoader for loading the SMP's SPI extensions.
  * The class loader implementation is heavily inspired by the Domibus PluginClassLoader.
  */
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/HttpForwardedHeaders.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/HttpForwardedHeaders.java
index 2316cd63c6eaa3497446c2029f27aee17ccc740a..13aa13fe2b888a624726dcf71e43ba6eafdce207 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/HttpForwardedHeaders.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/HttpForwardedHeaders.java
@@ -8,7 +8,7 @@ import javax.servlet.http.HttpServletRequest;
 
 /**
  * This class is initialized from HttpServletRequest's X-Forwarded-* headers.
- *
+ * <p>
  * The X-Forwarded-Host header defines which Host was used in the Client's request. In some RP implementations, it has only domain/ip
  * 'example.com' and (non-standard) X-Forwarded-Port is used for submitting port some implementations is combined with the port
  * as an example 'example.com:443'
@@ -24,14 +24,12 @@ public class HttpForwardedHeaders {
     private static final char HOST_PORT_SEPARATOR = ':';
 
 
-    enum ForwardedHeaderNameEnum {
+    public enum ForwardedHeaderNameEnum {
         HOST("X-Forwarded-Host"),
         PROTO("X-Forwarded-Proto"),
         FOR("X-Forwarded-For"),
         // non standard headers
-        PORT("X-Forwarded-Port"),
-        PREFIX("X-Forwarded-Prefix"),
-        SSL("X-Forwarded-Ssl");
+        PORT("X-Forwarded-Port");
 
         final String headerName;
 
@@ -44,12 +42,10 @@ public class HttpForwardedHeaders {
         }
     }
 
-
     final String host;
     final String port;
     final String proto;
     final String forClientHost;
-    final String ssl;
 
     public HttpForwardedHeaders(HttpServletRequest request) {
 
@@ -58,7 +54,6 @@ public class HttpForwardedHeaders {
             port = null;
             proto = null;
             forClientHost = null;
-            ssl = null;
             return;
         }
         // read the values
@@ -67,36 +62,34 @@ public class HttpForwardedHeaders {
         String portPrivate = getNormalizedHeader(request, ForwardedHeaderNameEnum.PORT);
         proto = getNormalizedHeader(request, ForwardedHeaderNameEnum.PROTO);
         forClientHost = getNormalizedHeader(request, ForwardedHeaderNameEnum.FOR);
-        ssl = getNormalizedHeader(request, ForwardedHeaderNameEnum.SSL);
         // normalize
-        if (StringUtils.contains(hostPrivate,HOST_PORT_SEPARATOR)) {
+        if (StringUtils.contains(hostPrivate, HOST_PORT_SEPARATOR)) {
             String hostCombined = hostPrivate;
-            hostPrivate = StringUtils.substringBefore(hostCombined,HOST_PORT_SEPARATOR);
-            portPrivate = validatePort(portPrivate,StringUtils.substringAfter(hostCombined,HOST_PORT_SEPARATOR));
+            hostPrivate = StringUtils.substringBefore(hostCombined, HOST_PORT_SEPARATOR);
+            portPrivate = validatePort(portPrivate, StringUtils.substringAfter(hostCombined, HOST_PORT_SEPARATOR));
         }
         host = hostPrivate;
         port = portPrivate;
     }
 
     private String getNormalizedHeader(HttpServletRequest request, ForwardedHeaderNameEnum header) {
-
         return StringUtils.lowerCase(StringUtils.trim(request.getHeader(header.getHeaderName())));
     }
 
-    private String validatePort(String headerPort, String hostPort){
+    private String validatePort(String headerPort, String hostPort) {
 
-        if (StringUtils.isBlank(headerPort)){
-            LOG.debug("Header X-Forwarded-Port is empty. Use port from X-Forwarded-Host [{}].",hostPort);
+        if (StringUtils.isBlank(headerPort)) {
+            LOG.debug("Header X-Forwarded-Port is empty. Use port from X-Forwarded-Host [{}].", hostPort);
             return hostPort;
         }
 
-        if (StringUtils.equals(headerPort, hostPort)){
-            LOG.debug("Header X-Forwarded-Port is and port from X-Forwarded-Host [{}] are equal.",hostPort);
+        if (StringUtils.equals(headerPort, hostPort)) {
+            LOG.debug("Header X-Forwarded-Port is and port from X-Forwarded-Host [{}] are equal.", hostPort);
             return headerPort;
         }
 
         LOG.warn("Header X-Forwarded-Port [{}] is and port from X-Forwarded-Host [{}] mismatch. Fix the RP/load balancer configuration! " +
-                "Host port will be used as default value!",headerPort, hostPort);
+                "Host port will be used as default value!", headerPort, hostPort);
         return headerPort;
     }
 
@@ -112,13 +105,13 @@ public class HttpForwardedHeaders {
     /**
      * Method returns null if the port is default port for given proto/schema.
      * For HTTP default port is 80 and for HTTPS default port is 443
-
+     *
      * @return non default ports or null
      */
     public String getNonDefaultPort() {
         if (StringUtils.equals("http", proto) && StringUtils.equals("80", port)
-            || StringUtils.equals("https", proto) && StringUtils.equals("443", port)) {
-            LOG.debug("Ignore default port [{}] for proto/schema [{}].",port, proto);
+                || StringUtils.equals("https", proto) && StringUtils.equals("443", port)) {
+            LOG.debug("Ignore default port [{}] for proto/schema [{}].", port, proto);
             return null;
         }
         return port;
@@ -132,10 +125,6 @@ public class HttpForwardedHeaders {
         return forClientHost;
     }
 
-    public String getSsl() {
-        return ssl;
-    }
-
     @Override
     public String toString() {
         return "HttpForwardedHeaders{" +
@@ -143,7 +132,6 @@ public class HttpForwardedHeaders {
                 ", port='" + port + '\'' +
                 ", proto='" + proto + '\'' +
                 ", forClientHost='" + forClientHost + '\'' +
-                ", ssl='" + ssl + '\'' +
                 '}';
     }
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/PropertyUtils.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/PropertyUtils.java
index 66406391c6d2afe5461aa12da07eedc4f875d1fa..f12a899acee8abdb4c411fae4a60607a225d2357 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/PropertyUtils.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/PropertyUtils.java
@@ -7,6 +7,7 @@ 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.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.commons.validator.routines.EmailValidator;
 import org.apache.commons.validator.routines.UrlValidator;
 import org.springframework.scheduling.support.CronExpression;
@@ -15,6 +16,7 @@ import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.Arrays;
+import java.util.Optional;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 import java.util.stream.Collectors;
@@ -24,8 +26,10 @@ import static org.apache.commons.lang3.StringUtils.*;
 public class PropertyUtils {
 
 
+    private static final String MASKED_VALUE = "*******";
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(PropertyUtils.class);
-    private static final String REG_EXP_SEPARATOR = "\\|";
+    private static final String REG_EXP_VALUE_SEPARATOR = "\\|";
+    private static final String REG_EXP_MAP_SEPARATOR = ":";
 
     private static UrlValidator urlValidator = new UrlValidator(new String[]{"http", "https"}, UrlValidator.ALLOW_LOCAL_URLS);
 
@@ -36,7 +40,6 @@ public class PropertyUtils {
             if (prop.isMandatory()) {
                 throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Empty mandatory property: " + prop.getProperty());
             }
-            ;
             return null;
         }
 
@@ -44,64 +47,26 @@ public class PropertyUtils {
         return parsePropertyType(type, value, rootFolder);
     }
 
-    public static boolean isValidProperty(SMPPropertyEnum prop, String value) {
+    public static boolean isValidProperty(SMPPropertyEnum prop, String value, File confFolder) {
         if (StringUtils.isBlank(value)) {
             // empty/ null value is invalid
             return !prop.isMandatory();
         }
         SMPPropertyTypeEnum type = prop.getPropertyType();
-        return isValidPropertyType(type, value);
+        return isValidPropertyType(type, value, confFolder);
     }
 
-    public static boolean isValidPropertyType(SMPPropertyTypeEnum type, String value) {
+    public static boolean isValidPropertyType(SMPPropertyTypeEnum type, String value, File confFolder) {
         if (StringUtils.isBlank(value)) {
             return false;
         }
-
-        switch (type) {
-            case BOOLEAN:
-                return value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false");
-            case EMAIL:
-                return EmailValidator.getInstance().isValid(value);
-            case REGEXP:
-                try {
-                    Pattern.compile(value);
-                    return true;
-                } catch (PatternSyntaxException exception) {
-                    return false;
-                }
-            case CRON_EXPRESSION:
-                return CronExpression.isValidExpression(value);
-            case INTEGER:
-                try {
-                    Integer.parseInt(value);
-                    return true;
-                } catch (NumberFormatException exception) {
-                    return false;
-                }
-            case PATH: {
-                File f = new File(value);
-                if (!f.exists()) {
-                    LOG.warn("Folder {} not exists. Try to create the folder.", f.getAbsolutePath());
-                    if (f.mkdirs()) {
-                        LOG.info("Folder {} created.", f.getAbsolutePath());
-                    }
-                    ;
-                }
-                return f.exists() && f.isDirectory();
-            }
-            // nothing to validate
-            case URL:
-                return urlValidator.isValid(value);
-            case LIST_STRING:
-            case MAP_STRING:
-            case FILENAME:
-            case STRING:
-                return true;
+        try {
+            parsePropertyType(type, value, confFolder);
+            return true;
+        } catch (SMPRuntimeException ex) {
+            LOG.debug("Invalid property value [{}] for type [{}]. Error: " , value, type, ExceptionUtils.getRootCauseMessage(ex));
+            return false;
         }
-        // property va
-
-        return true;
     }
 
     public static Object parsePropertyType(SMPPropertyTypeEnum type, String value, File rootFolder) {
@@ -111,50 +76,99 @@ public class PropertyUtils {
 
         switch (type) {
             case BOOLEAN:
-                return Boolean.valueOf(value.trim());
+                if(StringUtils.equalsAnyIgnoreCase(trim(value),"true","false")) {
+                    return Boolean.valueOf(value.trim());
+                }
+                throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Invalid boolean value: ["
+                        + value + "]. Error: Only {true, false} are allowed!");
             case REGEXP:
                 try {
                     return Pattern.compile(value);
-                } catch (PatternSyntaxException exception) {
-                    throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Invalid regular expression: " + value);
+                } catch (PatternSyntaxException ex) {
+                    throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Invalid regular expression: ["
+                            + value + "]. Error:" + ExceptionUtils.getRootCauseMessage(ex), ex);
                 }
             case INTEGER:
                 try {
                     return Integer.parseInt(value);
-                } catch (NumberFormatException exception) {
-                    throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Invalid integer: " + value);
+                } catch (NumberFormatException ex) {
+                    throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Invalid integer: ["
+                            + value + "]. Error:" + ExceptionUtils.getRootCauseMessage(ex), ex);
                 }
             case LIST_STRING: {
-                return Arrays.asList(value.split(REG_EXP_SEPARATOR));
+                return Arrays.asList(value.split(REG_EXP_VALUE_SEPARATOR));
             }
             case MAP_STRING: {
-                return Arrays.asList(value.split(REG_EXP_SEPARATOR)).stream().collect(Collectors.toMap(
-                        val -> trim(substringBefore(val, ":")), val -> trim(substringAfter(val, ":"))));
+                if (!value.contains(value)) {
+                    throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Invalid map: ["
+                            + value + "]. Error: Map must have at least one key:value entry!");
+                }
+                return Arrays.asList(value.split(REG_EXP_VALUE_SEPARATOR)).stream().collect(Collectors.toMap(
+                        val -> trim(substringBefore(val, REG_EXP_MAP_SEPARATOR)), val -> trim(substringAfter(val, REG_EXP_MAP_SEPARATOR))));
             }
             case PATH: {
+                File file = new File(rootFolder, value);
+                if (!file.exists() && !file.mkdirs()) {
+                    throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Folder: ["
+                            + value + "] does not exist, and can not be created!");
+                }
+                if (!file.isDirectory()) {
+                    throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Path: [" + value + "] is not folder!");
+                }
                 return new File(value);
             }
             // nothing to validate
             case FILENAME:
-                return new File(rootFolder, value);
+                File file = new File(rootFolder, value);
+                if (!file.exists()) {
+                    LOG.warn("File: [{}] does not exist. Full path: [{}].",value,  file.getAbsolutePath());
+                }
+                return file;
             case EMAIL:
                 String trimVal = value.trim();
                 if (EmailValidator.getInstance().isValid(trimVal)) {
                     return trimVal;
                 } else {
-                    throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Invalid email address: " + value);
+                    throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Invalid email address: [" + value + "].");
                 }
             case URL:
                 try {
                     return new URL(value.trim());
-                } catch (MalformedURLException e) {
-                    throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Invalid URL address: " + value);
+                } catch (MalformedURLException ex) {
+                    throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Invalid URL address:  ["
+                            + value + "]. Error:" + ExceptionUtils.getRootCauseMessage(ex), ex);
                 }
             case STRING:
                 return value;
         }
-        // property va
-
         return null;
     }
+
+
+    /**
+     * Return true for properties with sensitive data. For example the property value must not be logged
+     * or returned via WS!
+     *
+     * @param property - value to validate if contains sensitive data
+     * @return true if data is sensitive, else return false
+     */
+    public static boolean isSensitiveData(String property) {
+        Optional<SMPPropertyEnum> propOpt = SMPPropertyEnum.getByProperty(trim(property));
+        if (propOpt.isPresent()) {
+            return propOpt.get().isEncrypted() || property.toLowerCase().contains(".password.decrypted");
+        }
+        LOG.warn("Database property [{}] is not recognized by the SMP!", property);
+        return false;
+    }
+
+    /**
+     * Method returns 'masked' value for sensitive property data
+     *
+     * @param property
+     * @param value
+     * @return masked value for sensitive properties. Else it returns value!
+     */
+    public static String getMaskedData(String property, String value) {
+        return isSensitiveData(property) ? MASKED_VALUE : value;
+    }
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/SecurityUtils.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/SecurityUtils.java
index 0c99cd58d5d3c6b7e385f7b35be01a441a980440..7f056e4c0fb0cd5e2a7d3788434a470fbd4728be 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/SecurityUtils.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/SecurityUtils.java
@@ -2,6 +2,8 @@ package eu.europa.ec.edelivery.smp.utils;
 
 import eu.europa.ec.edelivery.smp.data.ui.AccessTokenRO;
 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.RandomStringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
@@ -21,10 +23,12 @@ import java.time.OffsetDateTime;
 import java.util.Arrays;
 import java.util.Base64;
 import java.util.Enumeration;
+import java.util.Random;
 
 import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.INTERNAL_ERROR;
 
 public class SecurityUtils {
+    public static final SMPLogger LOG = SMPLoggerFactory.getLogger(SecurityUtils.class);
 
     public static class Secret {
         final byte[] vector;
@@ -112,13 +116,13 @@ public class SecurityUtils {
         return newAlias;
     }
 
-    public static String generateAuthenticationToken() {
-        String newKeyPassword;
 
+    public static String generateAuthenticationToken(boolean devMode) {
+        String newKeyPassword;
         try {
             newKeyPassword = RandomStringUtils.random(DEFAULT_PASSWORD_LENGTH, 0, VALID_PW_CHARS.length(),
                     false, false,
-                    VALID_PW_CHARS.toCharArray(), SecureRandom.getInstanceStrong());
+                    VALID_PW_CHARS.toCharArray(), devMode ? new Random() : SecureRandom.getInstanceStrong());
 
         } catch (NoSuchAlgorithmException e) {
             String msg = "Error occurred while generation test password: No strong random algorithm. Error:"
@@ -143,11 +147,11 @@ public class SecurityUtils {
         return newKeyPassword;
     }
 
-    public static AccessTokenRO generateAccessToken() {
+    public static AccessTokenRO generateAccessToken(boolean testMode) {
         AccessTokenRO accessToken = new AccessTokenRO();
         accessToken.setGeneratedOn(OffsetDateTime.now());
         accessToken.setIdentifier(generateAuthenticationTokenIdentifier());
-        accessToken.setValue(generateAuthenticationToken());
+        accessToken.setValue(generateAuthenticationToken(testMode));
         return accessToken;
     }
 
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/SessionSecurityUtils.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/SessionSecurityUtils.java
index ae803480f1f6696fdc911651d5292d75445ed9b2..4753cda3ce87dfc05129d750ed7a97076b41f9e2 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/SessionSecurityUtils.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/SessionSecurityUtils.java
@@ -27,7 +27,7 @@ public class SessionSecurityUtils {
      * '
      * Currently authentication tokens supported to create na UI session.
      */
-    public static final List<Class> sessionAuthenticationClasses = Arrays.asList(SMPAuthenticationToken.class,
+    protected static final List<Class> sessionAuthenticationClasses = Arrays.asList(SMPAuthenticationToken.class,
             CasAuthenticationToken.class);
 
     /**
diff --git a/smp-server-library/src/main/resources/alert-mail-templates/credential_expired.ftl b/smp-server-library/src/main/resources/alert-mail-templates/credential_expired.ftl
index 465446ce8d23eb6aaae276539d2a90057f717b91..0e33f951d41ce81c546cdfeabf040d02a3255d9d 100644
--- a/smp-server-library/src/main/resources/alert-mail-templates/credential_expired.ftl
+++ b/smp-server-library/src/main/resources/alert-mail-templates/credential_expired.ftl
@@ -107,7 +107,6 @@
             <!-- / MARGIN RIGHT -->
           </tr>
         </table>
-
         </td>
     </tr>
   </table>
diff --git a/smp-server-library/src/main/resources/alert-mail-templates/credential_suspended.ftl b/smp-server-library/src/main/resources/alert-mail-templates/credential_suspended.ftl
index 53c653cf13f909294c90fae482451d8e2fba56e6..b12b3a20d74c164f4210cd747b28c0ae8d620681 100644
--- a/smp-server-library/src/main/resources/alert-mail-templates/credential_suspended.ftl
+++ b/smp-server-library/src/main/resources/alert-mail-templates/credential_suspended.ftl
@@ -59,7 +59,7 @@
                             <!-- TITLE -->
                             <tr>
                               <td valign="top" align="left" style=" font-size: 20px; font-family: Arial, Helvetica, sans-serif; color: #000;"><br/>
-                                Account is suspended</td>
+                                Account is temporarily suspended</td>
                             </tr>
                             <!-- / TITLE --> 
                             
@@ -83,7 +83,7 @@
                                   <p><strong>Failed login attempt count:</strong> ${FAILED_LOGIN_ATTEMPT}</p>
                                   <p><strong>Last failed login time:</strong> ${LAST_LOGIN_FAILURE_DATETIME}</p>
                                   <p><strong>Suspended util</strong> ${SUSPENDED_UNTIL_DATETIME}</p>
-                                  <p><strong>Reporting time:</strong> ${REPORTING_TIME}</p>
+                                  <p><strong>Reporting time:</strong> ${REPORTING_DATETIME}</p>
                                   <p><strong>Alert level:</strong> ${ALERT_LEVEL}</p>
                                   <p><strong>Server name:</strong> ${SERVER_NAME}</p>
                                 </td>
diff --git a/smp-server-library/src/main/resources/alert-mail-templates/credential_verification_failed.ftl b/smp-server-library/src/main/resources/alert-mail-templates/credential_verification_failed.ftl
index 9f3de0870dd7c9758cc1b93f61a9fe22e63e89af..f51e982892cc030af5e324f0a608e65684770ce1 100644
--- a/smp-server-library/src/main/resources/alert-mail-templates/credential_verification_failed.ftl
+++ b/smp-server-library/src/main/resources/alert-mail-templates/credential_verification_failed.ftl
@@ -59,7 +59,7 @@
                             <!-- TITLE -->
                             <tr>
                               <td valign="top" align="left" style=" font-size: 20px; font-family: Arial, Helvetica, sans-serif; color: #000;"><br/>
-                                Account is temporarly suspended</td>
+                                Mail verification failed!</td>
                             </tr>
                             <!-- / TITLE --> 
                             
@@ -82,7 +82,7 @@
                                   <p><strong>Credential id:</strong> ${CREDENTIAL_ID}</p>
                                   <p><strong>Failed login attempt count:</strong> ${FAILED_LOGIN_ATTEMPT}</p>
                                   <p><strong>Last failed login time:</strong> ${LAST_LOGIN_FAILURE_DATETIME}</p>
-                                  <p><strong>Reporting time:</strong> ${REPORTING_TIME}</p>
+                                  <p><strong>Reporting time:</strong> ${REPORTING_DATETIME}</p>
                                   <p><strong>Alert level:</strong> ${ALERT_LEVEL}</p>
                                   <p><strong>Server name:</strong> ${SERVER_NAME}</p>
                                 </td>
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/DatabaseConfigTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/DatabaseConfigTest.java
index 1a642977801ecb68469e12500e117e54c7a21fab..e3b1945097030e96c9472d0d1a1e17d38c1f5506 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/DatabaseConfigTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/DatabaseConfigTest.java
@@ -14,13 +14,19 @@ import static org.junit.Assert.*;
 
 public class DatabaseConfigTest {
 
+    public static final String DATABASE_DRIVER="org.h2.Driver";
+    public static final String DATABASE_DIALECT="org.hibernate.dialect.H2Dialect";
+    public static final String DATABASE_URL="jdbc:h2:file:./target/myDb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE;AUTO_SERVER=TRUE";
+    public static final String DATABASE_USERNAME="smp-dev";
+    public static final String DATABASE_PASS="smp-dev";
+
     DatabaseConfig testInstance = new DatabaseConfig(){{
         // test properties from persistence-test-h2.properties
         jndiDatasourceName =null;
-        driver = "org.h2.Driver";
-        url = "jdbc:h2:file:./target/myDb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE;AUTO_SERVER=TRUE";
-        username = "smp-dev";
-        password = "smp-dev";
+        driver = DATABASE_DRIVER;
+        url = DATABASE_URL;
+        username =DATABASE_USERNAME;
+        password =DATABASE_PASS;
     }};
 
     @Test
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/FilePropertyTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/FilePropertyTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d09f9c066e7e5dd09404b94a68ee8b3369199d07
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/FilePropertyTest.java
@@ -0,0 +1,39 @@
+package eu.europa.ec.edelivery.smp.config;
+
+import org.junit.Test;
+
+import java.util.Properties;
+
+import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.CLIENT_CERT_HEADER_ENABLED_DEPRECATED;
+import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.EXTERNAL_TLS_AUTHENTICATION_CLIENT_CERT_HEADER_ENABLED;
+import static org.junit.Assert.*;
+
+public class FilePropertyTest {
+
+    @Test
+    public void updateDeprecatedValues() {
+        String testValue = "test";
+        Properties prop = new Properties();
+        prop.setProperty(CLIENT_CERT_HEADER_ENABLED_DEPRECATED.getProperty(), testValue);
+
+        Properties result = FileProperty.updateDeprecatedValues(prop);
+
+        assertTrue(result.containsKey(EXTERNAL_TLS_AUTHENTICATION_CLIENT_CERT_HEADER_ENABLED.getProperty()));
+        assertEquals(testValue, result.getProperty(EXTERNAL_TLS_AUTHENTICATION_CLIENT_CERT_HEADER_ENABLED.getProperty()));
+    }
+
+    @Test
+    public void getFileProperties() {
+        Properties result = FileProperty.getFileProperties("/test-smp.config.properties");
+        assertNotNull(result);
+        assertEquals("This property is from custom file",result.getProperty("test.read.property"));
+    }
+
+    @Test
+    public void getFilePropertiesLegacyFallback() {
+        Properties result = FileProperty.getFileProperties("/prop-not-exists.properties");
+        assertNotNull(result);
+        // in the legacy fallback file the property is defined as: ${jdbc.user}
+        assertEquals("This property is from fallback legacy file",result.getProperty("test.read.property"));
+    }
+}
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/PropertyInitializationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/PropertyInitializationTest.java
index a65752040d09de685bc6214f98bfac95b51c52dd..8b0530351435477d9198fe1756a6e6d5dc276966 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/PropertyInitializationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/PropertyInitializationTest.java
@@ -3,25 +3,32 @@ package eu.europa.ec.edelivery.smp.config;
 import eu.europa.ec.edelivery.smp.data.model.DBConfiguration;
 import eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum;
 import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
+import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
 
 import javax.sql.DataSource;
 import java.util.Properties;
 
+import static eu.europa.ec.edelivery.smp.config.DatabaseConfigTest.*;
+import static eu.europa.ec.edelivery.smp.config.FileProperty.*;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
-public class PropertyInitializationTest {
 
+public class PropertyInitializationTest {
 
     PropertyInitialization testInstance = new PropertyInitialization();
 
     @Rule
     public ExpectedException expectedEx = ExpectedException.none();
 
-
     @Test
     public void testValidateProperties() {
         // when
@@ -60,7 +67,7 @@ public class PropertyInitializationTest {
     public void getDatasourceBadConfigurationWithUrl() {
         // when
         Properties properties = new Properties();
-        properties.setProperty(FileProperty.PROPERTY_DB_URL, "schema:/no@exists/db");
+        properties.setProperty(PROPERTY_DB_URL, "schema:/no@exists/db");
 
         expectedEx.expect(IllegalArgumentException.class);
         expectedEx.expectMessage("Property 'driverClassName' must not be empty");
@@ -71,10 +78,7 @@ public class PropertyInitializationTest {
 
     @Test
     public void getDatasourceByUrl() {
-        // when
-        Properties properties = new Properties();
-        properties.setProperty(FileProperty.PROPERTY_DB_URL, "jdbc:h2:file:./target/myDb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE;AUTO_SERVER=TRUE");
-        properties.setProperty(FileProperty.PROPERTY_DB_DRIVER, "org.h2.Driver");
+        Properties properties =  getTestFileProperties();
 
         DataSource dataSource = testInstance.getDatasource(properties);
 
@@ -102,4 +106,28 @@ public class PropertyInitializationTest {
         assertEquals(SMPPropertyEnum.CS_DOCUMENTS.getDesc(), entry.getDescription());
     }
 
+    @Test
+    public void getDatabaseProperties(){
+        Properties properties =  getTestFileProperties();
+
+        Properties databaseProperties = testInstance.getDatabaseProperties(properties);
+
+        assertNotNull(databaseProperties);
+
+    }
+
+    protected Properties getTestFileProperties(){
+        // create test database with SMP_CONFIGURATION TABLE
+        String url="jdbc:h2:mem:testdb;INIT=RUNSCRIPT FROM 'classpath:/create-configuration-table-h2.ddl'";
+        Properties properties = new Properties();
+        properties.setProperty(SMPPropertyEnum.CONFIGURATION_DIR.getProperty(), "./target/prop-init-test");
+        properties.setProperty(PROPERTY_DB_URL, url);
+        properties.setProperty(PROPERTY_DB_DIALECT, DATABASE_DIALECT);
+        properties.setProperty(FileProperty.PROPERTY_DB_DRIVER, DATABASE_DRIVER);
+        properties.setProperty(FileProperty.PROPERTY_DB_USER, DATABASE_USERNAME);
+        properties.setProperty(FileProperty.PROPERTY_DB_TOKEN, "");
+        properties.setProperty(FileProperty.PROPERTY_SMP_MODE_DEVELOPMENT, "true");
+        return properties;
+    }
+
 }
\ No newline at end of file
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/PropertyUpdateListenerTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/PropertyUpdateListenerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..90dfa6071db5e0fd8c6e1834790f13b981ae6862
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/PropertyUpdateListenerTest.java
@@ -0,0 +1,49 @@
+package eu.europa.ec.edelivery.smp.config;
+
+import eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.ACCESS_TOKEN_FAIL_DELAY;
+import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.SMP_PROPERTY_REFRESH_CRON;
+import static org.junit.Assert.*;
+
+public class PropertyUpdateListenerTest {
+
+    PropertyUpdateListener testInstance = Mockito.spy(new PropertyUpdateListener() {
+        @Override
+        public void updateProperties(Map<SMPPropertyEnum, Object> properties) {
+        }
+
+        @Override
+        public List<SMPPropertyEnum> handledProperties() {
+            return Collections.singletonList(ACCESS_TOKEN_FAIL_DELAY);
+        }
+    });
+
+    @Test
+    public void handlesProperty() {
+        assertTrue(testInstance.handlesProperty(ACCESS_TOKEN_FAIL_DELAY));
+        assertFalse(testInstance.handlesProperty(SMP_PROPERTY_REFRESH_CRON));
+    }
+
+    @Test
+    public void updateProperty() {
+        Mockito.doNothing().when(testInstance).updateProperties(Mockito.anyMap());
+        SMPPropertyEnum property = ACCESS_TOKEN_FAIL_DELAY;
+        String testValue = "test";
+
+        testInstance.updateProperty(property, testValue);
+
+        ArgumentCaptor<Map<SMPPropertyEnum, Object>> propertyCapture = ArgumentCaptor.forClass(Map.class);
+        Mockito.verify(testInstance, Mockito.times(1)).updateProperties(propertyCapture.capture());
+        assertEquals(1, propertyCapture.getValue().size());
+        assertTrue(propertyCapture.getValue().containsKey(ACCESS_TOKEN_FAIL_DELAY));
+        assertEquals(testValue, propertyCapture.getValue().get(ACCESS_TOKEN_FAIL_DELAY));
+    }
+}
\ No newline at end of file
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/UserDaoIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/UserDaoIntegrationTest.java
index 1e016c0af0e8f2e7ffa63fb662aba2c8d06c4539..68be572b22cf279c4f6babf84a7f6600bd3bbd90 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/UserDaoIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/UserDaoIntegrationTest.java
@@ -136,7 +136,7 @@ public class UserDaoIntegrationTest extends AbstractBaseDao {
         testInstance.persistFlushDetach(u);
 
         //test
-        Optional<DBUser> ou = testInstance.findUserByIdentifier(TestConstants.USERNAME_1);
+        Optional<DBUser> ou = testInstance.findUserByIdentifier(TestConstants.USERNAME_TOKEN_1);
         assertNotSame(u , ou.get());
         assertEquals(u, ou.get());
         assertEquals(u.getEmailAddress(), ou.get().getEmailAddress());
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 1544e94e4d475cd6088585c6a2d25cd41e9f177e..9bd050a3b8ec55f4ef04d1912c7ca3a3eb9ed2ab 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
@@ -11,6 +11,7 @@ import eu.europa.ec.edelivery.smp.data.model.DBServiceGroup;
 import eu.europa.ec.edelivery.smp.data.model.DBServiceMetadata;
 import eu.europa.ec.edelivery.smp.data.model.DBUser;
 import eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum;
+import eu.europa.ec.edelivery.smp.services.mail.MailService;
 import eu.europa.ec.edelivery.smp.services.ui.UIKeystoreService;
 import eu.europa.ec.edelivery.smp.services.ui.UITruststoreService;
 import eu.europa.ec.edelivery.smp.sml.SmlConnector;
@@ -41,13 +42,14 @@ import static eu.europa.ec.edelivery.smp.testutil.TestConstants.*;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(classes = {H2JPATestConfig.class,
-        CaseSensitivityNormalizer.class,SmlConnector.class,ServiceMetadataSigner.class,
+        CaseSensitivityNormalizer.class,SmlConnector.class,ServiceMetadataSigner.class, MailService.class,
         ServiceGroupService.class, DomainService.class, ServiceMetadataService.class,
-        ServiceGroupDao.class,ServiceMetadataDao.class, DomainDao.class, UserDao.class,DBAssertion.class, ConfigurationDao.class,
+        ServiceGroupDao.class,ServiceMetadataDao.class, DomainDao.class, UserDao.class,DBAssertion.class, ConfigurationDao.class, AlertDao.class,
         UITruststoreService.class, UIKeystoreService.class, ConversionTestConfig.class, SMLIntegrationService.class,
         CRLVerifierService.class,
         ConfigurationService.class,
-        ServicesBeansConfiguration.class})
+        ServicesBeansConfiguration.class,
+        AlertService.class})
 @Sql(scripts = {"classpath:cleanup-database.sql",
         "classpath:basic_conf_data-h2.sql"
 }, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AlertServiceTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AlertServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7822c704fb5ba3aa8ff1550a5cd6d90c140bf397
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AlertServiceTest.java
@@ -0,0 +1,402 @@
+package eu.europa.ec.edelivery.smp.services;
+
+import eu.europa.ec.edelivery.smp.data.dao.AlertDao;
+import eu.europa.ec.edelivery.smp.data.model.DBAlert;
+import eu.europa.ec.edelivery.smp.data.model.DBUser;
+import eu.europa.ec.edelivery.smp.data.ui.enums.AlertLevelEnum;
+import eu.europa.ec.edelivery.smp.data.ui.enums.AlertTypeEnum;
+import eu.europa.ec.edelivery.smp.data.ui.enums.CredentialTypeEnum;
+import eu.europa.ec.edelivery.smp.services.mail.MailModel;
+import eu.europa.ec.edelivery.smp.services.mail.MailService;
+import eu.europa.ec.edelivery.smp.services.mail.prop.CredentialSuspendedProperties;
+import eu.europa.ec.edelivery.smp.services.mail.prop.CredentialVerificationFailedProperties;
+import eu.europa.ec.edelivery.smp.services.mail.prop.CredentialsExpirationProperties;
+import eu.europa.ec.edelivery.smp.testutil.TestDBUtils;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+import java.time.OffsetDateTime;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+public class AlertServiceTest {
+
+    AlertDao alertDao = Mockito.mock(AlertDao.class);
+    MailService mailService = Mockito.mock(MailService.class);
+    ConfigurationService configurationService = Mockito.mock(ConfigurationService.class);
+
+
+    AlertService testInstance = new AlertService(alertDao, mailService, configurationService);
+
+    @Test
+    public void testCreateAlert() {
+        String mailSubject = "mailSubject";
+        String mailTo = "mailTo";
+        AlertLevelEnum level = AlertLevelEnum.MEDIUM;
+        AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_EXPIRED;
+
+        DBAlert alert = testInstance.createAlert(mailSubject, mailTo, level, alertType);
+
+        assertNotNull(alert);
+        assertNull(alert.getId());
+        assertEquals(mailSubject, alert.getMailSubject());
+        assertEquals(mailTo, alert.getMailTo());
+        assertEquals(level, alert.getAlertLevel());
+        assertEquals(alertType, alert.getAlertType());
+        assertFalse(alert.isProcessed());
+        assertNotNull(alert.getReportingTime());
+
+    }
+
+    @Test
+    public void testSubmitAlertMailNoMail() {
+
+        DBAlert alert = new DBAlert();
+
+        testInstance.submitAlertMail(alert);
+
+        verify(mailService, Mockito.never()).sendMail(Mockito.any(), Mockito.anyString(), Mockito.anyString());
+    }
+
+    @Test
+    public void alertBeforeUsernamePasswordExpire() {
+        // given
+        DBUser user = TestDBUtils.createDBUser("alertBeforeUsernamePasswordExpire");
+        String mailSubject = "mail subject";
+        String mailFrom = "mail.from@test.eu";
+        AlertLevelEnum alertLevel = AlertLevelEnum.MEDIUM;
+        user.setPasswordExpireOn(OffsetDateTime.now().plusDays(1));
+        doReturn(mailSubject).when(configurationService).getAlertBeforeExpirePasswordMailSubject();
+        doReturn(alertLevel).when(configurationService).getAlertBeforeExpirePasswordLevel();
+        doReturn(mailFrom).when(configurationService).getAlertEmailFrom();
+
+        AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_IMMINENT_EXPIRATION;
+        List<String> expectedTemplateProperties = Arrays.asList(CredentialsExpirationProperties.values()).stream()
+                .map(CredentialsExpirationProperties::name).collect(Collectors.toList());
+        // when
+        testInstance.alertBeforeUsernamePasswordExpire(user);
+        // then
+        assertAlertSend(alertType, user.getEmailAddress(), mailFrom, mailSubject,
+                expectedTemplateProperties);
+
+        verify(configurationService, times(1)).getAlertBeforeExpirePasswordMailSubject();
+        verify(configurationService, times(1)).getAlertBeforeExpirePasswordLevel();
+        verify(configurationService, times(1)).getAlertEmailFrom();
+    }
+
+    @Test
+    public void alertUsernamePasswordExpired() {
+        // given
+        DBUser user = TestDBUtils.createDBUser("alertUsernamePasswordExpired");
+        String mailSubject = "mail subject";
+        String mailFrom = "mail.from@test.eu";
+        AlertLevelEnum alertLevel = AlertLevelEnum.MEDIUM;
+        user.setPasswordExpireOn(OffsetDateTime.now().plusDays(1));
+        doReturn(mailSubject).when(configurationService).getAlertExpiredPasswordMailSubject();
+        doReturn(alertLevel).when(configurationService).getAlertExpiredPasswordLevel();
+        doReturn(mailFrom).when(configurationService).getAlertEmailFrom();
+        AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_EXPIRED;
+        List<String> expectedTemplateProperties = Arrays.asList(CredentialsExpirationProperties.values()).stream()
+                .map(CredentialsExpirationProperties::name).collect(Collectors.toList());
+        // when
+        testInstance.alertUsernamePasswordExpired(user);
+        // then
+        assertAlertSend(alertType, user.getEmailAddress(), mailFrom, mailSubject,
+                expectedTemplateProperties);
+
+        verify(configurationService, times(1)).getAlertExpiredPasswordMailSubject();
+        verify(configurationService, times(1)).getAlertExpiredPasswordLevel();
+        verify(configurationService, times(1)).getAlertEmailFrom();
+    }
+
+    @Test
+    public void alertBeforeAccessTokenExpire() {
+        // given
+        DBUser user = TestDBUtils.createDBUser("alertBeforeAccessTokenExpire");
+        String mailSubject = "mail subject";
+        String mailFrom = "mail.from@test.eu";
+        AlertLevelEnum alertLevel = AlertLevelEnum.MEDIUM;
+        user.setAccessTokenExpireOn(OffsetDateTime.now().plusDays(1));
+        doReturn(mailSubject).when(configurationService).getAlertBeforeExpireAccessTokenMailSubject();
+        doReturn(alertLevel).when(configurationService).getAlertBeforeExpireAccessTokenLevel();
+        doReturn(mailFrom).when(configurationService).getAlertEmailFrom();
+
+        AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_IMMINENT_EXPIRATION;
+        List<String> expectedTemplateProperties = Arrays.asList(CredentialsExpirationProperties.values()).stream()
+                .map(CredentialsExpirationProperties::name).collect(Collectors.toList());
+        // when
+        testInstance.alertBeforeAccessTokenExpire(user);
+        // then
+        assertAlertSend(alertType, user.getEmailAddress(), mailFrom, mailSubject,
+                expectedTemplateProperties);
+
+        verify(configurationService, times(1)).getAlertBeforeExpireAccessTokenMailSubject();
+        verify(configurationService, times(1)).getAlertBeforeExpireAccessTokenLevel();
+        verify(configurationService, times(1)).getAlertEmailFrom();
+    }
+
+    @Test
+    public void alertAccessTokenExpired() {
+        // given
+        DBUser user = TestDBUtils.createDBUser("alertAccessTokenExpired");
+        String mailSubject = "mail subject";
+        String mailFrom = "mail.from@test.eu";
+        AlertLevelEnum alertLevel = AlertLevelEnum.MEDIUM;
+        user.setAccessTokenExpireOn(OffsetDateTime.now().plusDays(1));
+        doReturn(mailSubject).when(configurationService).getAlertExpiredAccessTokenMailSubject();
+        doReturn(alertLevel).when(configurationService).getAlertExpiredAccessTokenLevel();
+        doReturn(mailFrom).when(configurationService).getAlertEmailFrom();
+        AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_EXPIRED;
+        List<String> expectedTemplateProperties = Arrays.asList(CredentialsExpirationProperties.values()).stream()
+                .map(CredentialsExpirationProperties::name).collect(Collectors.toList());
+        // when
+        testInstance.alertAccessTokenExpired(user);
+        // then
+        assertAlertSend(alertType, user.getEmailAddress(), mailFrom, mailSubject,
+                expectedTemplateProperties);
+
+        verify(configurationService, times(1)).getAlertExpiredAccessTokenMailSubject();
+        verify(configurationService, times(1)).getAlertExpiredAccessTokenLevel();
+        verify(configurationService, times(1)).getAlertEmailFrom();
+    }
+
+    @Test
+    public void alertBeforeCertificateExpire() {
+        // given
+        DBUser user = TestDBUtils.createDBUser("user", "alertBeforeCertificateExpire");
+        String mailSubject = "mail subject";
+        String mailFrom = "mail.from@test.eu";
+        AlertLevelEnum alertLevel = AlertLevelEnum.MEDIUM;
+        doReturn(mailSubject).when(configurationService).getAlertBeforeExpireCertificateMailSubject();
+        doReturn(alertLevel).when(configurationService).getAlertBeforeExpireCertificateLevel();
+        doReturn(mailFrom).when(configurationService).getAlertEmailFrom();
+        AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_IMMINENT_EXPIRATION;
+        List<String> expectedTemplateProperties = Arrays.asList(CredentialsExpirationProperties.values()).stream()
+                .map(CredentialsExpirationProperties::name).collect(Collectors.toList());
+        // when
+        testInstance.alertBeforeCertificateExpire(user);
+        // then
+        assertAlertSend(alertType, user.getEmailAddress(), mailFrom, mailSubject,
+                expectedTemplateProperties);
+
+        verify(configurationService, times(1)).getAlertBeforeExpireCertificateMailSubject();
+        verify(configurationService, times(1)).getAlertBeforeExpireCertificateLevel();
+        verify(configurationService, times(1)).getAlertEmailFrom();
+    }
+
+    @Test
+    public void alertCertificateExpired() {
+        // given
+        DBUser user = TestDBUtils.createDBUser("user", "alertCertificateExpired");
+        String mailSubject = "mail subject";
+        String mailFrom = "mail.from@test.eu";
+        AlertLevelEnum alertLevel = AlertLevelEnum.MEDIUM;
+        doReturn(mailSubject).when(configurationService).getAlertExpiredCertificateMailSubject();
+        doReturn(alertLevel).when(configurationService).getAlertExpiredCertificateLevel();
+        doReturn(mailFrom).when(configurationService).getAlertEmailFrom();
+        AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_EXPIRED;
+        List<String> expectedTemplateProperties = Arrays.asList(CredentialsExpirationProperties.values()).stream()
+                .map(CredentialsExpirationProperties::name).collect(Collectors.toList());
+
+        // when
+        testInstance.alertCertificateExpired(user);
+        // then
+        assertAlertSend(alertType, user.getEmailAddress(), mailFrom, mailSubject,
+                expectedTemplateProperties);
+
+        verify(configurationService, times(1)).getAlertExpiredCertificateMailSubject();
+        verify(configurationService, times(1)).getAlertExpiredCertificateLevel();
+        verify(configurationService, times(1)).getAlertEmailFrom();
+    }
+
+    @Test
+    public void submitAlertMail() {
+        String mailTo = "test.mail@domain.eu";
+        String mailFrom = "test.mail@domain.eu";
+        String mailSubject = "mailSubject";
+        AlertTypeEnum template = AlertTypeEnum.CREDENTIAL_IMMINENT_EXPIRATION;
+        DBAlert alert = new DBAlert();
+        alert.setAlertType(template);
+        alert.setMailTo(mailTo);
+        alert.setMailSubject(mailSubject);
+        alert.addProperty("test", "testValue");
+        doReturn(mailFrom).when(configurationService).getAlertEmailFrom();
+
+        testInstance.submitAlertMail(alert);
+
+        ArgumentCaptor<MailModel<Properties>> argModel = ArgumentCaptor.forClass(MailModel.class);
+        ArgumentCaptor<String> argMailTo = ArgumentCaptor.forClass(String.class);
+        ArgumentCaptor<String> argFrom = ArgumentCaptor.forClass(String.class);
+
+        verify(mailService, times(1))
+                .sendMail(argModel.capture(), argFrom.capture(), argMailTo.capture());
+        verify(alertDao, times(1)).update(alert);
+
+        assertEquals(mailTo, argMailTo.getValue());
+        assertEquals(mailFrom, argFrom.getValue());
+        assertEquals(mailSubject, argModel.getValue().getSubject());
+        assertEquals(template.getTemplate(), argModel.getValue().getTemplatePath());
+        assertEquals(1, argModel.getValue().getModel().size());
+    }
+
+    @Test
+    public void alertUsernameCredentialVerificationFailed() {
+        DBUser user = TestDBUtils.createDBUser("user");
+        String mailSubject = "mail subject";
+        String mailFrom = "mail.from@test.eu";
+        user.setSequentialLoginFailureCount(5);
+        user.setLastFailedLoginAttempt(OffsetDateTime.now());
+        AlertLevelEnum alertLevel = AlertLevelEnum.MEDIUM;
+
+        doReturn(true).when(configurationService).getAlertUserLoginFailureEnabled();
+        doReturn(mailSubject).when(configurationService).getAlertUserLoginFailureSubject();
+        doReturn(alertLevel).when(configurationService).getAlertUserLoginFailureLevel();
+        doReturn(mailFrom).when(configurationService).getAlertEmailFrom();
+
+        AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_VERIFICATION_FAILED;
+        List<String> expectedTemplateProperties = Arrays.asList(CredentialVerificationFailedProperties.values()).stream()
+                .map(CredentialVerificationFailedProperties::name).collect(Collectors.toList());
+
+        // when
+        testInstance.alertCredentialVerificationFailed(user, CredentialTypeEnum.USERNAME_PASSWORD);
+        // then
+        assertAlertSend(alertType, user.getEmailAddress(), mailFrom, mailSubject,
+                expectedTemplateProperties);
+
+        verify(configurationService, times(1)).getAlertUserLoginFailureEnabled();
+        verify(configurationService, times(1)).getAlertUserLoginFailureSubject();
+        verify(configurationService, times(1)).getAlertUserLoginFailureLevel();
+        verify(configurationService, times(1)).getAlertEmailFrom();
+    }
+
+    @Test
+    public void alertTokenCredentialVerificationFailed() {
+        DBUser user = TestDBUtils.createDBUser("user", "alertCertificateExpired");
+        String mailSubject = "mail subject";
+        String mailFrom = "mail.from@test.eu";
+        user.setSequentialTokenLoginFailureCount(5);
+        user.setLastTokenFailedLoginAttempt(OffsetDateTime.now());
+        AlertLevelEnum alertLevel = AlertLevelEnum.MEDIUM;
+
+        doReturn(true).when(configurationService).getAlertUserLoginFailureEnabled();
+        doReturn(mailSubject).when(configurationService).getAlertUserLoginFailureSubject();
+        doReturn(alertLevel).when(configurationService).getAlertUserLoginFailureLevel();
+        doReturn(mailFrom).when(configurationService).getAlertEmailFrom();
+        //doReturn(123456).when(configurationService).getLoginSuspensionTimeInSeconds();
+        AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_VERIFICATION_FAILED;
+        List<String> expectedTemplateProperties = Arrays.asList(CredentialVerificationFailedProperties.values()).stream()
+                .map(CredentialVerificationFailedProperties::name).collect(Collectors.toList());
+
+        // when
+        testInstance.alertCredentialVerificationFailed(user, CredentialTypeEnum.ACCESS_TOKEN);
+        // then
+        assertAlertSend(alertType, user.getEmailAddress(), mailFrom, mailSubject,
+                expectedTemplateProperties);
+
+        verify(configurationService, times(1)).getAlertUserLoginFailureEnabled();
+        verify(configurationService, times(1)).getAlertUserLoginFailureSubject();
+        verify(configurationService, times(1)).getAlertUserLoginFailureLevel();
+        verify(configurationService, times(1)).getAlertEmailFrom();
+    }
+
+    @Test
+    public void alertUsernameCredentialsSuspended() {
+        DBUser user = TestDBUtils.createDBUser("user", "alertCertificateExpired");
+        String mailSubject = "mail subject";
+        String mailFrom = "mail.from@test.eu";
+        user.setSequentialLoginFailureCount(5);
+        user.setLastFailedLoginAttempt(OffsetDateTime.now());
+        AlertLevelEnum alertLevel = AlertLevelEnum.MEDIUM;
+
+        doReturn(true).when(configurationService).getAlertUserSuspendedEnabled();
+        doReturn(mailSubject).when(configurationService).getAlertUserSuspendedSubject();
+        doReturn(alertLevel).when(configurationService).getAlertUserSuspendedLevel();
+        doReturn(mailFrom).when(configurationService).getAlertEmailFrom();
+        doReturn(123456).when(configurationService).getLoginSuspensionTimeInSeconds();
+        AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_SUSPENDED;
+        List<String> expectedTemplateProperties = Arrays.asList(CredentialSuspendedProperties.values()).stream()
+                .map(CredentialSuspendedProperties::name).collect(Collectors.toList());
+
+        // when
+        testInstance.alertCredentialsSuspended(user, CredentialTypeEnum.USERNAME_PASSWORD);
+        // then
+        assertAlertSend(alertType, user.getEmailAddress(), mailFrom, mailSubject,
+                expectedTemplateProperties);
+
+        verify(configurationService, times(1)).getAlertUserSuspendedEnabled();
+        verify(configurationService, times(1)).getAlertUserSuspendedSubject();
+        verify(configurationService, times(1)).getAlertUserSuspendedLevel();
+        verify(configurationService, times(1)).getAlertEmailFrom();
+    }
+
+    @Test
+    public void alertTokenCredentialsSuspended() {
+        DBUser user = TestDBUtils.createDBUser("user", "alertCertificateExpired");
+        String mailSubject = "mail subject";
+        String mailFrom = "mail.from@test.eu";
+        user.setSequentialTokenLoginFailureCount(5);
+        user.setLastTokenFailedLoginAttempt(OffsetDateTime.now());
+        AlertLevelEnum alertLevel = AlertLevelEnum.MEDIUM;
+
+        doReturn(true).when(configurationService).getAlertUserSuspendedEnabled();
+        doReturn(mailSubject).when(configurationService).getAlertUserSuspendedSubject();
+        doReturn(alertLevel).when(configurationService).getAlertUserSuspendedLevel();
+        doReturn(mailFrom).when(configurationService).getAlertEmailFrom();
+        doReturn(123456).when(configurationService).getLoginSuspensionTimeInSeconds();
+        AlertTypeEnum alertType = AlertTypeEnum.CREDENTIAL_SUSPENDED;
+        List<String> expectedTemplateProperties = Arrays.asList(CredentialSuspendedProperties.values()).stream()
+                .map(CredentialSuspendedProperties::name).collect(Collectors.toList());
+
+        // when
+        testInstance.alertCredentialsSuspended(user, CredentialTypeEnum.ACCESS_TOKEN);
+        // then
+        assertAlertSend(alertType, user.getEmailAddress(), mailFrom, mailSubject,
+                expectedTemplateProperties);
+
+        verify(configurationService, times(1)).getAlertUserSuspendedEnabled();
+        verify(configurationService, times(1)).getAlertUserSuspendedSubject();
+        verify(configurationService, times(1)).getAlertUserSuspendedLevel();
+        verify(configurationService, times(1)).getAlertEmailFrom();
+    }
+
+
+    public void assertAlertSend(AlertTypeEnum alertType, String mailTo, String mailFrom, String mailSubject,
+                                List<String> templateProperties) {
+
+        ArgumentCaptor<MailModel<Properties>> argModel = ArgumentCaptor.forClass(MailModel.class);
+        ArgumentCaptor<String> argMailFrom = ArgumentCaptor.forClass(String.class);
+        ArgumentCaptor<String> argMailTo = ArgumentCaptor.forClass(String.class);
+        ArgumentCaptor<DBAlert> argAlert = ArgumentCaptor.forClass(DBAlert.class);
+        ArgumentCaptor<DBAlert> argAlertUpdate = ArgumentCaptor.forClass(DBAlert.class);
+
+
+        verify(alertDao, times(1)).persistFlushDetach(argAlert.capture());
+        verify(mailService, times(1))
+                .sendMail(argModel.capture(), argMailFrom.capture(), argMailTo.capture());
+
+        verify(alertDao, times(1)).update(argAlertUpdate.capture());
+
+        assertEquals(mailTo, argMailTo.getValue());
+        assertEquals(mailFrom, argMailFrom.getValue());
+
+
+        MailModel<Properties> model = argModel.getValue();
+        assertEquals(alertType.getTemplate(), model.getTemplatePath());
+        assertEquals(mailSubject, model.getSubject());
+
+        // test to contain all properties
+        for (String prop : templateProperties) {
+
+            assertTrue(prop, model.getModel().keySet().contains(prop));
+        }
+        assertEquals(templateProperties.size(), model.getModel().size());
+
+
+    }
+}
\ No newline at end of file
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ConfigurationServiceAllGetMethodsTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ConfigurationServiceAllGetMethodsTest.java
index 5ae9b715809f214efcd95a80afebd03d2beb69c2..0cafecf101b35bbf2229f03f42fc3055ac9900e7 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ConfigurationServiceAllGetMethodsTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ConfigurationServiceAllGetMethodsTest.java
@@ -1,6 +1,7 @@
 package eu.europa.ec.edelivery.smp.services;
 
 import eu.europa.ec.edelivery.smp.data.dao.ConfigurationDao;
+import eu.europa.ec.edelivery.smp.data.ui.enums.AlertLevelEnum;
 import eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.commons.lang3.reflect.MethodUtils;
@@ -34,9 +35,6 @@ public class ConfigurationServiceAllGetMethodsTest {
         }
     }
 
-
-
-
     ConfigurationDao configurationDaoMock = mock(ConfigurationDao.class);
     ConfigurationService testInstance = new ConfigurationService(configurationDaoMock);
 
@@ -50,13 +48,14 @@ public class ConfigurationServiceAllGetMethodsTest {
                 //{HTTP_FORWARDED_HEADERS_ENABLED, Boolean.TRUE, "", true},
                 {HTTP_HSTS_MAX_AGE, 1234, "getHttpHeaderHstsMaxAge", true},
                 {HTTP_HEADER_SEC_POLICY, TEST_STRING, "getHttpHeaderContentSecurityPolicy", true},
-                //{HTTP_PROXY_HOST,TEST_STRING, "", true},
-                {HTTP_NO_PROXY_HOSTS, TEST_STRING, "getHttpNoProxyHosts", false},
+                {HTTP_NO_PROXY_HOSTS,TEST_STRING, "getHttpNoProxyHosts", false},
+                {HTTP_PROXY_HOST, TEST_STRING, "getHttpProxyHost", false},
                 {HTTP_PROXY_PASSWORD, TEST_STRING, "getProxyCredentialToken", true},
-                //{HTTP_PROXY_PORT, TEST_STRING, "", true},
+                {HTTP_PROXY_PORT, 8800, "getHttpProxyPort", true},
                 {HTTP_PROXY_USER, TEST_STRING, "getProxyUsername", true},
                 {PARTC_SCH_REGEXP, TEST_REXEXP,"getParticipantIdentifierSchemeRexExp", true},
-                {PARTC_SCH_REGEXP_MSG, TEST_STRING, "getParticipantIdentifierSchemeRexExpMessage", true},
+                {PARTC_SCH_REGEXP, TEST_STRING, "getParticipantIdentifierSchemeRexExpPattern", false},
+                {PARTC_EBCOREPARTYID_CONCATENATE, Boolean.FALSE, "getForceConcatenateEBCorePartyId", true},
                 {CS_PARTICIPANTS, TEST_STRING_LIST, "getCaseSensitiveParticipantScheme", true},
                 {CS_DOCUMENTS, TEST_STRING_LIST, "getCaseSensitiveDocumentScheme", true},
                 {SML_ENABLED, Boolean.FALSE, "isSMLIntegrationEnabled", true},
@@ -87,6 +86,11 @@ public class ConfigurationServiceAllGetMethodsTest {
                 {PASSWORD_POLICY_REGULAR_EXPRESSION, TEST_REXEXP, "getPasswordPolicyRexExp", true},
                 {PASSWORD_POLICY_MESSAGE, TEST_STRING, "getPasswordPolicyValidationMessage", false},
                 {PASSWORD_POLICY_VALID_DAYS, 2, "getPasswordPolicyValidDays", true},
+                {PASSWORD_POLICY_REGULAR_EXPRESSION, TEST_STRING, "getPasswordPolicyRexExpPattern", false},
+                {PASSWORD_POLICY_WARNING_DAYS_BEFORE_EXPIRE, 10, "getPasswordPolicyUIWarningDaysBeforeExpire", true},
+                {PASSWORD_POLICY_FORCE_CHANGE_EXPIRED, Boolean.TRUE, "getPasswordPolicyForceChangeIfExpired", true},
+                {USER_LOGIN_FAIL_DELAY,1000, "getLoginFailDelayInMilliSeconds", true},
+                {ACCESS_TOKEN_FAIL_DELAY,1000, "getAccessTokenLoginFailDelayInMilliSeconds", true},
                 {USER_MAX_FAILED_ATTEMPTS, 55, "getLoginMaxAttempts", true},
                 {USER_SUSPENSION_TIME, 3600, "getLoginSuspensionTimeInSeconds", true},
                 {ACCESS_TOKEN_POLICY_VALID_DAYS, 1212, "getAccessTokenPolicyValidDays", true},
@@ -101,6 +105,45 @@ public class ConfigurationServiceAllGetMethodsTest {
                 {SSO_CAS_TOKEN_VALIDATION_URLPATH, TEST_STRING, "getCasURLTokenValidation", true},
                 {SSO_CAS_TOKEN_VALIDATION_PARAMS, TEST_MAP, "getCasTokenValidationParams", true},
                 {SSO_CAS_TOKEN_VALIDATION_GROUPS, TEST_STRING_LIST, "getCasURLTokenValidationGroups", true},
+                {PARTC_EBCOREPARTYID_CONCATENATE, Boolean.FALSE, "getForceConcatenateEBCorePartyId", true},
+                {PARTC_SCH_MANDATORY, Boolean.FALSE, "getParticipantSchemeMandatory", true},
+                {SMP_CLUSTER_ENABLED, Boolean.FALSE, "isClusterEnabled", true},
+                {ENCODED_SLASHES_ALLOWED_IN_URL, Boolean.FALSE, "encodedSlashesAllowedInUrl", true},
+                {SMP_ALERT_CREDENTIALS_SERVER, TEST_STRING, "getTargetServerForCredentialValidation", true},
+                {SML_TLS_SERVER_CERT_SUBJECT_REGEXP, TEST_STRING, "getSMLIntegrationServerCertSubjectRegExpPattern", false},
+                {SSO_CAS_SMP_LOGIN_URI, TEST_STRING, "getCasSMPLoginRelativePath", true},
+                {ALERT_USER_LOGIN_FAILURE_ENABLED, Boolean.FALSE, "getAlertUserLoginFailureEnabled", true},
+                {ALERT_USER_SUSPENDED_ENABLED,  Boolean.FALSE, "getAlertUserSuspendedEnabled", true},
+                {ALERT_USER_SUSPENDED_MAIL_SUBJECT, TEST_STRING, "getAlertUserSuspendedSubject", true},
+                {ALERT_PASSWORD_BEFORE_EXPIRATION_ENABLED,  Boolean.FALSE, "getAlertBeforeExpirePasswordEnabled", true},
+                {ALERT_PASSWORD_BEFORE_EXPIRATION_PERIOD, 10, "getAlertBeforeExpirePasswordPeriod", true},
+                {ALERT_PASSWORD_BEFORE_EXPIRATION_INTERVAL, 10, "getAlertBeforeExpirePasswordInterval", true},
+                {ALERT_PASSWORD_BEFORE_EXPIRATION_MAIL_SUBJECT, TEST_STRING, "getAlertBeforeExpirePasswordMailSubject", true},
+                {ALERT_PASSWORD_EXPIRED_ENABLED,  Boolean.FALSE, "getAlertExpiredPasswordEnabled", true},
+                {ALERT_PASSWORD_EXPIRED_PERIOD, 10, "getAlertExpiredPasswordPeriod", true},
+                {ALERT_PASSWORD_EXPIRED_INTERVAL, 10, "getAlertExpiredPasswordInterval", true},
+                {ALERT_PASSWORD_EXPIRED_MAIL_SUBJECT, TEST_STRING, "getAlertExpiredPasswordMailSubject", true},
+                {ALERT_ACCESS_TOKEN_BEFORE_EXPIRATION_ENABLED,  Boolean.FALSE, "getAlertBeforeExpireAccessTokenEnabled", true},
+                {ALERT_ACCESS_TOKEN_BEFORE_EXPIRATION_PERIOD, 10, "getAlertBeforeExpireAccessTokenPeriod", true},
+                {ALERT_ACCESS_TOKEN_BEFORE_EXPIRATION_INTERVAL, 10, "getAlertBeforeExpireAccessTokenInterval", true},
+                {ALERT_ACCESS_TOKEN_BEFORE_EXPIRATION_MAIL_SUBJECT, TEST_STRING, "getAlertBeforeExpireAccessTokenMailSubject", true},
+                {ALERT_ACCESS_TOKEN_EXPIRED_ENABLED,  Boolean.FALSE, "getAlertExpiredAccessTokenEnabled", true},
+                {ALERT_ACCESS_TOKEN_EXPIRED_PERIOD, 10, "getAlertExpiredAccessTokenPeriod", true},
+                {ALERT_ACCESS_TOKEN_EXPIRED_INTERVAL, 10, "getAlertExpiredAccessTokenInterval", true},
+                {ALERT_ACCESS_TOKEN_EXPIRED_MAIL_SUBJECT, TEST_STRING, "getAlertExpiredAccessTokenMailSubject", true},
+
+                {ALERT_CERTIFICATE_BEFORE_EXPIRATION_ENABLED,  Boolean.FALSE, "getAlertBeforeExpireCertificateEnabled", true},
+                {ALERT_CERTIFICATE_BEFORE_EXPIRATION_PERIOD, 10, "getAlertBeforeExpireCertificatePeriod", true},
+                {ALERT_CERTIFICATE_BEFORE_EXPIRATION_INTERVAL, 10, "getAlertBeforeExpireCertificateInterval", true},
+                {ALERT_CERTIFICATE_BEFORE_EXPIRATION_MAIL_SUBJECT, TEST_STRING, "getAlertBeforeExpireCertificateMailSubject", true},
+
+                {ALERT_CERTIFICATE_EXPIRED_ENABLED,  Boolean.FALSE, "getAlertExpiredCertificateEnabled", true},
+                {ALERT_CERTIFICATE_EXPIRED_PERIOD, 10, "getAlertExpiredCertificatePeriod", true},
+                {ALERT_CERTIFICATE_EXPIRED_INTERVAL, 10, "getAlertExpiredCertificateInterval", true},
+                {ALERT_CERTIFICATE_EXPIRED_MAIL_SUBJECT, TEST_STRING, "getAlertExpiredCertificateMailSubject", true},
+                {SMP_ALERT_BATCH_SIZE, 10, "getAlertCredentialsBatchSize", true},
+                {SMP_ALERT_MAIL_FROM, TEST_STRING, "getAlertEmailFrom", true},
+
         });
     }
     private final SMPPropertyEnum property;
@@ -124,7 +167,10 @@ public class ConfigurationServiceAllGetMethodsTest {
             doReturn(value).when(configurationDaoMock).getCachedProperty(property);
         }
         Object result = MethodUtils.invokeExactMethod(testInstance, methodName);
-
-        assertEquals(value, result);
+        if (result instanceof  Optional){
+            assertEquals(value, ((Optional<?>) result).get());
+        }else {
+            assertEquals(value, result);
+        }
     }
 }
\ No newline at end of file
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/CredentialValidatorServiceTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/CredentialValidatorServiceTest.java
index 8feea6c635334a0e5766c32c6fd16f17184b8b61..8db66fa83699f50bf62ca264782d502b1b27e81a 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/CredentialValidatorServiceTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/CredentialValidatorServiceTest.java
@@ -1,15 +1,18 @@
 package eu.europa.ec.edelivery.smp.services;
 
 import eu.europa.ec.edelivery.smp.data.dao.UserDao;
+import eu.europa.ec.edelivery.smp.data.model.DBUser;
 import eu.europa.ec.edelivery.smp.utils.HttpUtils;
 import org.junit.Assert;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 
+import java.util.Collections;
 import java.util.regex.Pattern;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 
@@ -48,4 +51,202 @@ public class CredentialValidatorServiceTest {
         assertFalse(result);
         verify(mockConfigService, Mockito.times(1)).getTargetServerForCredentialValidation();
     }
+
+    @Test
+    public void validateCredentialsForBeforeExpireUsernames() {
+        DBUser user = Mockito.mock(DBUser.class);
+        Integer iPeriod = 10;
+        Integer iInterval = 15;
+        Integer iBatchSize = 20;
+
+        doReturn(true).when(mockConfigService).getAlertBeforeExpirePasswordEnabled();
+        doReturn(iPeriod).when(mockConfigService).getAlertBeforeExpirePasswordPeriod();
+        doReturn(iInterval).when(mockConfigService).getAlertBeforeExpirePasswordInterval();
+        doReturn(iBatchSize).when(mockConfigService).getAlertCredentialsBatchSize();
+        doReturn(Collections.singletonList(user)).when(mockUserDao).getBeforePasswordExpireUsersForAlerts(anyInt(), anyInt(), anyInt());
+
+        testInstance.validateCredentialsForBeforeExpireUsernames();
+
+
+        ArgumentCaptor<Integer> period = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> interval = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> batchSize = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<DBUser> userCapture = ArgumentCaptor.forClass(DBUser.class);
+
+
+        verify(mockUserDao, Mockito.times(1))
+                .getBeforePasswordExpireUsersForAlerts(period.capture(), interval.capture(), batchSize.capture());
+        verify(mockAlertService, Mockito.times(1))
+                .alertBeforeUsernamePasswordExpire(userCapture.capture());
+
+        assertEquals(iPeriod, period.getValue());
+        assertEquals(iInterval, interval.getValue());
+        assertEquals(iBatchSize, batchSize.getValue());
+        assertEquals(user, userCapture.getValue());
+    }
+
+    @Test
+    public void validateCredentialsForExpiredUsernames() {
+        DBUser user = Mockito.mock(DBUser.class);
+        Integer iPeriod = 10;
+        Integer iInterval = 15;
+        Integer iBatchSize = 20;
+
+        doReturn(true).when(mockConfigService).getAlertExpiredPasswordEnabled();
+        doReturn(iPeriod).when(mockConfigService).getAlertExpiredPasswordPeriod();
+        doReturn(iInterval).when(mockConfigService).getAlertExpiredPasswordInterval();
+        doReturn(iBatchSize).when(mockConfigService).getAlertCredentialsBatchSize();
+        doReturn(Collections.singletonList(user)).when(mockUserDao).getPasswordExpiredUsersForAlerts(anyInt(), anyInt(), anyInt());
+
+        testInstance.validateCredentialsForExpiredUsernames();
+
+
+        ArgumentCaptor<Integer> period = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> interval = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> batchSize = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<DBUser> userCapture = ArgumentCaptor.forClass(DBUser.class);
+
+
+        verify(mockUserDao, Mockito.times(1))
+                .getPasswordExpiredUsersForAlerts(period.capture(), interval.capture(), batchSize.capture());
+        verify(mockAlertService, Mockito.times(1))
+                .alertUsernamePasswordExpired(userCapture.capture());
+
+        assertEquals(iPeriod, period.getValue());
+        assertEquals(iInterval, interval.getValue());
+        assertEquals(iBatchSize, batchSize.getValue());
+        assertEquals(user, userCapture.getValue());
+    }
+
+    @Test
+    public void validateCredentialsForBeforeExpireAccessToken() {
+        DBUser user = Mockito.mock(DBUser.class);
+        Integer iPeriod = 10;
+        Integer iInterval = 15;
+        Integer iBatchSize = 20;
+
+        doReturn(true).when(mockConfigService).getAlertBeforeExpireAccessTokenEnabled();
+        doReturn(iPeriod).when(mockConfigService).getAlertBeforeExpireAccessTokenPeriod();
+        doReturn(iInterval).when(mockConfigService).getAlertBeforeExpireAccessTokenInterval();
+        doReturn(iBatchSize).when(mockConfigService).getAlertCredentialsBatchSize();
+        doReturn(Collections.singletonList(user)).when(mockUserDao).getBeforeAccessTokenExpireUsersForAlerts(anyInt(), anyInt(), anyInt());
+
+        testInstance.validateCredentialsForBeforeExpireAccessToken();
+
+
+        ArgumentCaptor<Integer> period = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> interval = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> batchSize = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<DBUser> userCapture = ArgumentCaptor.forClass(DBUser.class);
+
+
+        verify(mockUserDao, Mockito.times(1))
+                .getBeforeAccessTokenExpireUsersForAlerts(period.capture(), interval.capture(), batchSize.capture());
+        verify(mockAlertService, Mockito.times(1))
+                .alertBeforeAccessTokenExpire(userCapture.capture());
+
+        assertEquals(iPeriod, period.getValue());
+        assertEquals(iInterval, interval.getValue());
+        assertEquals(iBatchSize, batchSize.getValue());
+        assertEquals(user, userCapture.getValue());
+    }
+
+    @Test
+    public void validateCredentialsForExpiredAccessToken() {
+        DBUser user = Mockito.mock(DBUser.class);
+        Integer iPeriod = 10;
+        Integer iInterval = 15;
+        Integer iBatchSize = 20;
+
+        doReturn(true).when(mockConfigService).getAlertExpiredAccessTokenEnabled();
+        doReturn(iPeriod).when(mockConfigService).getAlertExpiredAccessTokenPeriod();
+        doReturn(iInterval).when(mockConfigService).getAlertExpiredAccessTokenInterval();
+        doReturn(iBatchSize).when(mockConfigService).getAlertCredentialsBatchSize();
+        doReturn(Collections.singletonList(user)).when(mockUserDao).getAccessTokenExpiredUsersForAlerts(anyInt(), anyInt(), anyInt());
+
+        testInstance.validateCredentialsForExpiredAccessToken();
+
+
+        ArgumentCaptor<Integer> period = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> interval = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> batchSize = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<DBUser> userCapture = ArgumentCaptor.forClass(DBUser.class);
+
+
+        verify(mockUserDao, Mockito.times(1))
+                .getAccessTokenExpiredUsersForAlerts(period.capture(), interval.capture(), batchSize.capture());
+        verify(mockAlertService, Mockito.times(1))
+                .alertAccessTokenExpired(userCapture.capture());
+
+        assertEquals(iPeriod, period.getValue());
+        assertEquals(iInterval, interval.getValue());
+        assertEquals(iBatchSize, batchSize.getValue());
+        assertEquals(user, userCapture.getValue());
+    }
+
+    @Test
+    public void validateCredentialsForBeforeExpireCertificate() {
+        DBUser user = Mockito.mock(DBUser.class);
+        Integer iPeriod = 10;
+        Integer iInterval = 15;
+        Integer iBatchSize = 20;
+
+        doReturn(true).when(mockConfigService).getAlertBeforeExpireCertificateEnabled();
+        doReturn(iPeriod).when(mockConfigService).getAlertBeforeExpireCertificatePeriod();
+        doReturn(iInterval).when(mockConfigService).getAlertBeforeExpireCertificateInterval();
+        doReturn(iBatchSize).when(mockConfigService).getAlertCredentialsBatchSize();
+        doReturn(Collections.singletonList(user)).when(mockUserDao).getBeforeCertificateExpireUsersForAlerts(anyInt(), anyInt(), anyInt());
+
+        testInstance.validateCredentialsForBeforeExpireCertificate();
+
+
+        ArgumentCaptor<Integer> period = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> interval = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> batchSize = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<DBUser> userCapture = ArgumentCaptor.forClass(DBUser.class);
+
+
+        verify(mockUserDao, Mockito.times(1))
+                .getBeforeCertificateExpireUsersForAlerts(period.capture(), interval.capture(), batchSize.capture());
+        verify(mockAlertService, Mockito.times(1))
+                .alertBeforeCertificateExpire(userCapture.capture());
+
+        assertEquals(iPeriod, period.getValue());
+        assertEquals(iInterval, interval.getValue());
+        assertEquals(iBatchSize, batchSize.getValue());
+        assertEquals(user, userCapture.getValue());
+    }
+
+    @Test
+    public void validateCredentialsForExpiredCertificate() {
+        DBUser user = Mockito.mock(DBUser.class);
+        Integer iPeriod = 10;
+        Integer iInterval = 15;
+        Integer iBatchSize = 20;
+
+        doReturn(true).when(mockConfigService).getAlertExpiredCertificateEnabled();
+        doReturn(iPeriod).when(mockConfigService).getAlertExpiredCertificatePeriod();
+        doReturn(iInterval).when(mockConfigService).getAlertExpiredCertificateInterval();
+        doReturn(iBatchSize).when(mockConfigService).getAlertCredentialsBatchSize();
+        doReturn(Collections.singletonList(user)).when(mockUserDao).getCertificateExpiredUsersForAlerts(anyInt(), anyInt(), anyInt());
+
+        testInstance.validateCredentialsForExpiredCertificate();
+
+
+        ArgumentCaptor<Integer> period = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> interval = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> batchSize = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<DBUser> userCapture = ArgumentCaptor.forClass(DBUser.class);
+
+
+        verify(mockUserDao, Mockito.times(1))
+                .getCertificateExpiredUsersForAlerts(period.capture(), interval.capture(), batchSize.capture());
+        verify(mockAlertService, Mockito.times(1))
+                .alertCertificateExpired(userCapture.capture());
+
+        assertEquals(iPeriod, period.getValue());
+        assertEquals(iInterval, interval.getValue());
+        assertEquals(iBatchSize, batchSize.getValue());
+        assertEquals(user, userCapture.getValue());
+    }
 }
\ No newline at end of file
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/PayloadValidatorServiceTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/PayloadValidatorServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5cdf7798831ef79a2f00f5d6cd3b1b4b3fa49e0e
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/PayloadValidatorServiceTest.java
@@ -0,0 +1,82 @@
+package eu.europa.ec.edelivery.smp.services;
+
+import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
+import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
+import eu.europa.ec.smp.spi.PayloadValidatorSpi;
+import eu.europa.ec.smp.spi.exceptions.PayloadValidatorSpiException;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.MatcherAssert;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.springframework.util.MimeTypeUtils;
+
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Optional;
+
+import static org.junit.Assert.*;
+
+public class PayloadValidatorServiceTest {
+
+    @Test
+    public void validateUploadedContentNoValidatorsMostNotFail() {
+        PayloadValidatorService testInstance = new PayloadValidatorService(Optional.empty());
+        InputStream inputStream = Mockito.mock(InputStream.class);
+
+        testInstance.validateUploadedContent(inputStream, MimeTypeUtils.APPLICATION_JSON.getType());
+        // no error should accrue
+    }
+
+    @Test
+    public void validateUploadedContentNoValidatorsMostNotFailEmpty() {
+        PayloadValidatorService testInstance = new PayloadValidatorService(Optional.of(Collections.emptyList()));
+        InputStream inputStream = Mockito.mock(InputStream.class);
+
+        testInstance.validateUploadedContent(inputStream, MimeTypeUtils.APPLICATION_JSON.getType());
+        // no error should accrue
+    }
+
+    @Test
+    public void validateUploadedContent() throws PayloadValidatorSpiException {
+        PayloadValidatorSpi validatorSpi1  = Mockito.mock(PayloadValidatorSpi.class);
+        PayloadValidatorSpi validatorSpi2  = Mockito.mock(PayloadValidatorSpi.class);
+        PayloadValidatorService testInstance = new PayloadValidatorService(Optional.of(Arrays.asList(validatorSpi1,validatorSpi2)));
+        InputStream inputStream = Mockito.mock(InputStream.class);
+        String mimeType = MimeTypeUtils.APPLICATION_JSON.getType();
+
+
+        testInstance.validateUploadedContent(inputStream, mimeType);
+        // no error should accrue
+        ArgumentCaptor<InputStream> streamCapture1 = ArgumentCaptor.forClass(InputStream.class);
+        ArgumentCaptor<String> mimeTypeCapture1 = ArgumentCaptor.forClass(String.class);
+        ArgumentCaptor<InputStream> streamCapture2 = ArgumentCaptor.forClass(InputStream.class);
+        ArgumentCaptor<String> mimeTypeCapture2 = ArgumentCaptor.forClass(String.class);
+        Mockito.verify(validatorSpi1, Mockito.times(1)).validatePayload(streamCapture1.capture(), mimeTypeCapture1.capture());
+        Mockito.verify(validatorSpi2,Mockito.times(1)).validatePayload(streamCapture2.capture(), mimeTypeCapture2.capture());
+
+        assertEquals(inputStream, streamCapture1.getValue());
+        assertEquals(inputStream, streamCapture2.getValue());
+        assertEquals(mimeType, mimeTypeCapture1.getValue());
+        assertEquals(mimeType, mimeTypeCapture2.getValue());
+    }
+
+    @Test
+    public void validateUploadedContentThrowException() throws PayloadValidatorSpiException {
+        PayloadValidatorSpi validatorSpi1  = Mockito.mock(PayloadValidatorSpi.class);
+        PayloadValidatorService testInstance = new PayloadValidatorService(Optional.of(Arrays.asList(validatorSpi1)));
+        InputStream inputStream = Mockito.mock(InputStream.class);
+        String mimeType = MimeTypeUtils.APPLICATION_JSON.getType();
+        PayloadValidatorSpiException spiException = new PayloadValidatorSpiException("TestError");
+        Mockito.doThrow(spiException).when(validatorSpi1).validatePayload(Mockito.any(),Mockito.any());
+
+
+        SMPRuntimeException smpRuntimeException =
+                assertThrows(SMPRuntimeException.class, () -> testInstance.validateUploadedContent(inputStream, mimeType));
+
+        assertEquals(ErrorCode.INVALID_REQUEST, smpRuntimeException.getErrorCode());
+        MatcherAssert.assertThat(smpRuntimeException.getMessage(), CoreMatchers.containsString(spiException.getMessage()));
+    }
+}
\ No newline at end of file
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceMultipleDomainsIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceMultipleDomainsIntegrationTest.java
index 6e4a2491570500913de4d3fab8a1787ff150a891..48ab3062600c9980592357cc4a1e2839b62518a5 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceMultipleDomainsIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceMultipleDomainsIntegrationTest.java
@@ -85,8 +85,8 @@ public class ServiceGroupServiceMultipleDomainsIntegrationTest extends AbstractS
         assertFalse(dbsg.isPresent()); // test if exists - it must not :)
 
         // when
-        boolean bCreated = testInstance.saveServiceGroup(inServiceGroup, TEST_DOMAIN_CODE_2, TestConstants.USERNAME_1,
-                TestConstants.USERNAME_1);
+        boolean bCreated = testInstance.saveServiceGroup(inServiceGroup, TEST_DOMAIN_CODE_2, TestConstants.USERNAME_TOKEN_1,
+                TestConstants.USERNAME_TOKEN_1);
         Optional<DBServiceGroup> optRes = dbAssertion.findAndInitServiceGroup(TEST_SG_ID_PL, TEST_SG_SCHEMA_2);
 
         // then
@@ -111,8 +111,8 @@ public class ServiceGroupServiceMultipleDomainsIntegrationTest extends AbstractS
         assertNotEquals(extension, newExtension); // extension updated
 
         // when
-        boolean bCreated = testInstance.saveServiceGroup(inServiceGroup, TEST_DOMAIN_CODE_1, TestConstants.USERNAME_1,
-                TestConstants.USERNAME_1);
+        boolean bCreated = testInstance.saveServiceGroup(inServiceGroup, TEST_DOMAIN_CODE_1, ""+ TestConstants.USERNAME_TOKEN_1,
+                TestConstants.USERNAME_TOKEN_1);
         serviceGroupDao.clearPersistenceContext();
 
         Optional<DBServiceGroup> optRes = dbAssertion.findAndInitServiceGroup(TEST_SG_ID_2, TEST_SG_SCHEMA_2);
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceSingleDomainIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceSingleDomainIntegrationTest.java
index 8d450fa490127a7de350039bae9d7fc22a69c6e3..5c61019cf9c16f74d489bac760e41026618520fd 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceSingleDomainIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceSingleDomainIntegrationTest.java
@@ -100,8 +100,8 @@ public class ServiceGroupServiceSingleDomainIntegrationTest extends AbstractServ
         DBDomain domain = domainDao.getTheOnlyDomain().get();
         assertNotNull(domain);
         // when
-        boolean bCreated = testInstance.saveServiceGroup(inServiceGroup, null, TestConstants.USERNAME_1,
-                TestConstants.USERNAME_1);
+        boolean bCreated = testInstance.saveServiceGroup(inServiceGroup, null, TestConstants.USERNAME_TOKEN_1,
+                TestConstants.USERNAME_TOKEN_1);
 
         Optional<DBServiceGroup> optRes= serviceGroupDao.findServiceGroup(TEST_SG_ID_PL, TEST_SG_SCHEMA_2);
 
@@ -122,8 +122,8 @@ public class ServiceGroupServiceSingleDomainIntegrationTest extends AbstractServ
        assertNotNull(domain);
 
        // when
-       boolean bCreated = testInstance.saveServiceGroup(inServiceGroup, domain.getDomainCode(), TestConstants.USERNAME_1,
-               TestConstants.USERNAME_1);
+       boolean bCreated = testInstance.saveServiceGroup(inServiceGroup, domain.getDomainCode(), TestConstants.USERNAME_TOKEN_1,
+               TestConstants.USERNAME_TOKEN_1);
 
 
        Optional<DBServiceGroup> optRes= serviceGroupDao.findServiceGroup(TEST_SG_ID_PL, TEST_SG_SCHEMA_2);
@@ -148,8 +148,8 @@ public class ServiceGroupServiceSingleDomainIntegrationTest extends AbstractServ
         assertFalse(Arrays.equals(extension, newExtension)); // extension updated
 
         // when
-        boolean bCreated = testInstance.saveServiceGroup(inServiceGroup, domain.getDomainCode(), TestConstants.USERNAME_1,
-                TestConstants.USERNAME_1);
+        boolean bCreated = testInstance.saveServiceGroup(inServiceGroup, domain.getDomainCode(), TestConstants.USERNAME_TOKEN_1,
+                TestConstants.USERNAME_TOKEN_1);
 
 
         Optional<DBServiceGroup> optRes= serviceGroupDao.findServiceGroup(TEST_SG_ID_PL, TEST_SG_SCHEMA_2);
@@ -174,8 +174,8 @@ public class ServiceGroupServiceSingleDomainIntegrationTest extends AbstractServ
     public void saveAndDeletePositiveScenario() throws IOException {
         // given
         ServiceGroup inServiceGroup = unmarshal(loadDocumentAsString(TestConstants.SERVICE_GROUP_POLAND_XML_PATH));
-        boolean bCreated = testInstance.saveServiceGroup(inServiceGroup, null, TestConstants.USERNAME_1,
-                TestConstants.USERNAME_1);
+        boolean bCreated = testInstance.saveServiceGroup(inServiceGroup, null, TestConstants.USERNAME_TOKEN_1,
+                TestConstants.USERNAME_TOKEN_1);
         assertTrue(bCreated);
         serviceGroupDao.clearPersistenceContext();
 
@@ -277,7 +277,7 @@ public class ServiceGroupServiceSingleDomainIntegrationTest extends AbstractServ
         expectedExeption.expectMessage(DOMAIN_NOT_EXISTS.getMessage(domain));
 
         //execute
-        testInstance.saveServiceGroup(inServiceGroup, domain, USERNAME_1, USERNAME_1);
+        testInstance.saveServiceGroup(inServiceGroup, domain, USERNAME_TOKEN_1, USERNAME_TOKEN_1);
     }
 
     @Test
@@ -290,7 +290,7 @@ public class ServiceGroupServiceSingleDomainIntegrationTest extends AbstractServ
                 DomainService.DOMAIN_ID_PATTERN.pattern()));
 
         //execute
-        testInstance.saveServiceGroup(inServiceGroup, domain, USERNAME_1, USERNAME_1);
+        testInstance.saveServiceGroup(inServiceGroup, domain, USERNAME_TOKEN_1, USERNAME_TOKEN_1);
     }
 
     @Test
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIPropertyServiceIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIPropertyServiceIntegrationTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..bfabe011c619250ece09af20f505b42dcb8bf86d
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIPropertyServiceIntegrationTest.java
@@ -0,0 +1,150 @@
+package eu.europa.ec.edelivery.smp.services.ui;
+
+import eu.europa.ec.edelivery.smp.cron.CronTriggerConfig;
+import eu.europa.ec.edelivery.smp.cron.SMPDynamicCronTrigger;
+import eu.europa.ec.edelivery.smp.data.dao.ConfigurationDao;
+import eu.europa.ec.edelivery.smp.data.model.DBConfiguration;
+import eu.europa.ec.edelivery.smp.data.ui.PropertyRO;
+import eu.europa.ec.edelivery.smp.data.ui.PropertyValidationRO;
+import eu.europa.ec.edelivery.smp.data.ui.ServiceResultProperties;
+import eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum;
+import eu.europa.ec.edelivery.smp.services.AbstractServiceIntegrationTest;
+import org.apache.commons.lang3.StringUtils;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.MatcherAssert;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.test.context.ContextConfiguration;
+
+import java.util.Collections;
+import java.util.Map;
+
+import static eu.europa.ec.edelivery.smp.cron.CronTriggerConfig.TRIGGER_BEAN_PROPERTY_REFRESH;
+import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.SMP_CLUSTER_ENABLED;
+import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.SMP_PROPERTY_REFRESH_CRON;
+import static org.junit.Assert.*;
+
+@ContextConfiguration(classes = {UIPropertyService.class, CronTriggerConfig.class})
+public class UIPropertyServiceIntegrationTest extends AbstractServiceIntegrationTest {
+
+
+    @Autowired
+    protected UIPropertyService testInstance;
+    @Autowired @Qualifier(TRIGGER_BEAN_PROPERTY_REFRESH)
+    SMPDynamicCronTrigger refreshPropertiesTrigger;
+
+
+
+    @Test
+    public void getTableListAll() {
+
+        //when
+        ServiceResultProperties res = testInstance.getTableList(-1, -1, null, null, null);
+        // then
+        assertNotNull(res);
+        assertEquals(SMPPropertyEnum.values().length, res.getCount().intValue());
+        assertEquals(-1, res.getPage().intValue());
+        assertEquals(-1, res.getPageSize().intValue());
+        assertEquals(SMPPropertyEnum.values().length, res.getServiceEntities().size());
+        assertNull(res.getFilter());
+    }
+
+    @Test
+    public void getTableListFilterByCas() {
+
+        //when
+        String filter = ".cas";
+        ServiceResultProperties res = testInstance.getTableList(-1, -1, null, null, filter);
+        // then
+        assertNotNull(res);
+        assertTrue(res.getCount().intValue() < SMPPropertyEnum.values().length);
+        assertEquals(-1, res.getPage().intValue());
+        assertEquals(-1, res.getPageSize().intValue());
+        for (PropertyRO propertyRO : res.getServiceEntities()) {
+            assertTrue(StringUtils.containsIgnoreCase(propertyRO.getProperty(), filter));
+        }
+        assertEquals(filter, res.getFilter());
+    }
+
+    @Test
+    public void createPropertyPendingToUpdate() {
+        SMPPropertyEnum propertyType = SMP_PROPERTY_REFRESH_CRON;
+        DBConfiguration dbConfiguration = new DBConfiguration();
+        dbConfiguration.setProperty(propertyType.getProperty());
+        dbConfiguration.setValue("1 1 * * * *");
+
+        Map<String, DBConfiguration> dbProperties = Collections.singletonMap(propertyType.getProperty(), dbConfiguration);
+        PropertyRO propertyRO = testInstance.createProperty(propertyType, dbProperties);
+
+        assertEquals(dbConfiguration.getProperty(), propertyRO.getProperty());
+        assertEquals(propertyType.getDesc(), propertyRO.getDesc());
+        assertEquals(configurationDao.getCachedProperty(propertyType), propertyRO.getValue());
+
+        assertEquals(dbConfiguration.getValue(), propertyRO.getNewValue());
+        assertEquals(refreshPropertiesTrigger.getNextExecutionDate(), propertyRO.getUpdateDate());
+
+        assertEquals(propertyType.isEncrypted(), propertyRO.isEncrypted());
+        assertEquals(propertyType.isMandatory(), propertyRO.isMandatory());
+        assertEquals(propertyType.isRestartNeeded(), propertyRO.isRestartNeeded());
+}
+
+    @Test
+    public void updatePropertyList() {
+        configurationDao.setPropertyToDatabase(SMP_PROPERTY_REFRESH_CRON.getProperty(), SMP_PROPERTY_REFRESH_CRON.getDefValue());
+        // set non cluster - to enable instant refresh
+        configurationDao.setPropertyToDatabase(SMP_CLUSTER_ENABLED.getProperty(), "false");
+        configurationDao.reloadPropertiesFromDatabase();
+
+        SMPPropertyEnum propertyType = SMP_PROPERTY_REFRESH_CRON;
+        String value = "2 1 * * * *";
+        PropertyRO propertyRO = new PropertyRO(propertyType.getProperty(), value);
+        assertNotEquals(value, configurationDao.getCachedProperty(propertyType));
+
+        testInstance.updatePropertyList(Collections.singletonList(propertyRO));
+        assertEquals(value, configurationDao.getCachedProperty(propertyType));
+
+    }
+    @Test
+    public void validatePropertyNotExists() {
+        String propertyName="DoesNotExist";
+        String propertyValue="DoesNotExistValue";
+        PropertyRO property = new PropertyRO(propertyName, propertyValue);
+
+        PropertyValidationRO result = testInstance.validateProperty(property);
+        assertNotNull(result);
+        assertEquals(propertyName, result.getProperty());
+        assertEquals(propertyValue, result.getValue());
+        assertFalse(result.isPropertyValid());
+        MatcherAssert.assertThat(result.getErrorMessage(), CoreMatchers.containsString("Property ["+propertyName+"] is not SMP property!"));
+    }
+
+    @Test
+    public void validatePropertyInvalidValue() {
+        String propertyName=SMPPropertyEnum.ACCESS_TOKEN_FAIL_DELAY.getProperty();
+        String propertyValue="NotANumber";
+        PropertyRO property = new PropertyRO(propertyName, propertyValue);
+
+        PropertyValidationRO result = testInstance.validateProperty(property);
+        assertNotNull(result);
+        assertEquals(propertyName, result.getProperty());
+        assertEquals(propertyValue, result.getValue());
+        assertFalse(result.isPropertyValid());
+        MatcherAssert.assertThat(result.getErrorMessage(), CoreMatchers.containsString("Invalid integer: ["+propertyValue+"]. Error:NumberFormatException: For input string: \""+propertyValue+"\"!"));
+    }
+
+    @Test
+    public void validatePropertyOK() {
+        String propertyName=SMPPropertyEnum.ACCESS_TOKEN_FAIL_DELAY.getProperty();
+        String propertyValue="1223232";
+        PropertyRO property = new PropertyRO(propertyName, propertyValue);
+
+        PropertyValidationRO result = testInstance.validateProperty(property);
+        assertNotNull(result);
+        assertEquals(propertyName, result.getProperty());
+        assertEquals(propertyValue, result.getValue());
+        assertTrue(result.isPropertyValid());
+        assertNull(result.getErrorMessage());
+    }
+
+}
\ No newline at end of file
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 ce1333c7c7e5d6233c5dcc85bb7bb959fcee3ccb..4ff730c833db882ec1656056b8f42994b655d0c6 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
@@ -4,6 +4,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.AccessTokenRO;
 import eu.europa.ec.edelivery.smp.data.ui.CertificateRO;
 import eu.europa.ec.edelivery.smp.data.ui.ServiceResult;
 import eu.europa.ec.edelivery.smp.data.ui.UserRO;
@@ -16,6 +17,7 @@ import org.junit.rules.ExpectedException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.crypto.bcrypt.BCrypt;
 import org.springframework.test.context.ContextConfiguration;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.time.OffsetDateTime;
 import java.time.temporal.ChronoUnit;
@@ -38,6 +40,8 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
     @Autowired
     protected UIUserService testInstance;
 
+
+
     protected void insertDataObjects(int size) {
         for (int i = 0; i < size; i++) {
             DBUser d = TestDBUtils.createDBUserByUsername("user" + i);
@@ -266,7 +270,31 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
 
         assertEquals(urTest.getServiceEntities().size() - 1, iCntNew);
         assertFalse(rmUsr.isPresent());
+    }
+
+    @Test
+    @Transactional
+    public void testGenerateAccessTokenForUser() {
+        String userPassword=UUID.randomUUID().toString();
+        DBUser user = new DBUser();
+        user.setPassword(BCrypt.hashpw(userPassword, BCrypt.gensalt()));
+        user.setUsername(UUID.randomUUID().toString());
+        user.setEmailAddress(UUID.randomUUID().toString());
+        user.setRole("ROLE");
+        userDao.persistFlushDetach(user);
+
+
+        AccessTokenRO token = testInstance.generateAccessTokenForUser(user.getId(), userPassword);
 
+        Optional<DBUser> optResult = userDao.findUserByAuthenticationToken(token.getIdentifier());
+        assertTrue(optResult.isPresent());
+        assertNotNull(token);
+        DBUser result = optResult.get();
+        assertEquals(user.getUsername(), result.getUsername());
+        assertEquals(result.getAccessTokenIdentifier(), token.getIdentifier());
+        assertTrue(BCrypt.checkpw(token.getValue(), result.getAccessToken()));
+        assertNotNull(result.getAccessTokenExpireOn());
+        assertNotNull(result.getAccessTokenGeneratedOn());
     }
 
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java
index 1b5f3d9f1f868dcffd8fdbf2fb0f4f9318e01a19..f027304a457fee8416314387732e283199041384 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java
@@ -18,33 +18,33 @@ public class TestConstants {
     public static final String TEST_SG_ID_3 = "0007:002:utest";
     public static final String TEST_SG_ID_4 = "0007:004:utest";
     public static final String TEST_SG_ID_NO_SCHEME = "No-Scheme-Party-Id";
-    public static final String TEST_SG_ID_PL= "urn:poland:ncpb:utest";
-    public static final String TEST_SG_ID_PL2= "urn:Poland:ncpb";
-
+    public static final String TEST_SG_ID_PL = "urn:poland:ncpb:utest";
+    public static final String TEST_SG_ID_PL2 = "urn:Poland:ncpb";
 
     public static final String TEST_SG_SCHEMA_1 = "iso6523-actorid-upis";
     public static final String TEST_SG_SCHEMA_2 = "ehealth-actorid-qns";
     public static final String TEST_SG_SCHEMA_PL2 = "eHealth-participantId-qns";
 
-
-
-
     public static final String TEST_DOC_SCHEMA_1 = "busdox-docid-qns";
     public static final String TEST_DOC_SCHEMA_2 = "ehealth-resid-qns";
-    public static final String TEST_DOC_SCHEMA_PL2="eHealth-resId-qns";
+    public static final String TEST_DOC_SCHEMA_PL2 = "eHealth-resId-qns";
 
     public static final String TEST_DOC_ID_1 = "urn:oasis:names:specification:ubl:schema:xsd:Invoice-12::Invoice##urn:www.cenbii.eu:transaction:biicoretrdm010:ver1.0:#urn:www.peppol.eu:bis:peppol4a:ver1.0::2.0";
     public static final String TEST_DOC_ID_2 = "docid.007";
     public static final String TEST_DOC_ID_PL2 = "DocId.007";
 
 
+    public static final String TOKEN_PREFIX = "token-";
     public static final String USERNAME_1 = "test-user_001";
     public static final String USERNAME_2 = "test-user_002";
     public static final String USERNAME_3 = "test-user_003";
+    public static final String USERNAME_TOKEN_1 = TOKEN_PREFIX + USERNAME_1;
+    public static final String USERNAME_TOKEN_2 = TOKEN_PREFIX + USERNAME_2;
+    public static final String USERNAME_TOKEN_3 = TOKEN_PREFIX + USERNAME_3;
 
-    public static final String USER_CERT_1="CN=utest common name 01,O=org,C=BE:0000000000000066";
-    public static final String USER_CERT_2="CN=utest common name 02,O=org,C=BE:0000000000000077";
-    public static final String USER_CERT_3="CN=utest common name 03,O=org,C=BE:0000000000000077";
+    public static final String USER_CERT_1 = "CN=utest common name 01,O=org,C=BE:0000000000000066";
+    public static final String USER_CERT_2 = "CN=utest common name 02,O=org,C=BE:0000000000000077";
+    public static final String USER_CERT_3 = "CN=utest common name 03,O=org,C=BE:0000000000000077";
 
 
     public static final String SERVICE_GROUP_POLAND_XML_PATH = "/examples/services/ServiceGroupPoland.xml";
@@ -52,16 +52,16 @@ public class TestConstants {
     public static final String SERVICE_METADATA_XML_PATH = "/examples/services/ServiceMetadataPoland.xml";
     public static final String SIGNED_SERVICE_METADATA_XML_PATH = "/examples/services/SignedServiceMetadataPoland.xml";
 
-    public static final ParticipantIdentifierType SERVICE_GROUP_ID = asParticipantId("participant-scheme-qns::urn:eu:ncpb",false);
+    public static final ParticipantIdentifierType SERVICE_GROUP_ID = asParticipantId("participant-scheme-qns::urn:eu:ncpb", false);
 
     public static final String ADMIN_USERNAME = "test_admin";
-    public static final String CERT_USER="CN=common name,O=org,C=BE:0000000000000066";
-    public static final String CERT_USER_ENCODED="CN%3Dcommon%20name%2CO%3Dorg%2CC%3DBE%3A0000000000000066";
+    public static final String CERT_USER = "CN=common name,O=org,C=BE:0000000000000066";
+    public static final String CERT_USER_ENCODED = "CN%3Dcommon%20name%2CO%3Dorg%2CC%3DBE%3A0000000000000066";
 
     // parameter: custom string as content
     public static final String SIMPLE_EXTENSION_XML ="<Extension xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\"><ex:dummynode xmlns:ex=\"http://test.eu\">Sample not mandatory extension: %s</ex:dummynode></Extension>";
     //5 parameters: ParticipantScheme, ParticipantIdentifier, DocumentScheme, DocumentIdentifier, custom value
-    public static final String SIMPLE_DOCUMENT_XML ="<ServiceMetadata xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\"><ServiceInformation><ParticipantIdentifier scheme=\"%s\">%s</ParticipantIdentifier><DocumentIdentifier scheme=\"%s\">%s</DocumentIdentifier><ProcessList><Process><ProcessIdentifier scheme=\"cenbii-procid-ubl\">urn:www.cenbii.eu:profile:bii04:ver1.0</ProcessIdentifier><ServiceEndpointList><Endpoint transportProfile=\"bdxr-transport-ebms3-as4-v1p0\"><EndpointURI>http://localhost:8080/domibus-weblogic/services/msh</EndpointURI><RequireBusinessLevelSignature>true</RequireBusinessLevelSignature><ServiceActivationDate>2003-01-01T00:00:00</ServiceActivationDate><ServiceExpirationDate>2099-05-01T00:00:00</ServiceExpirationDate>" +
+    public static final String SIMPLE_DOCUMENT_XML = "<ServiceMetadata xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\"><ServiceInformation><ParticipantIdentifier scheme=\"%s\">%s</ParticipantIdentifier><DocumentIdentifier scheme=\"%s\">%s</DocumentIdentifier><ProcessList><Process><ProcessIdentifier scheme=\"cenbii-procid-ubl\">urn:www.cenbii.eu:profile:bii04:ver1.0</ProcessIdentifier><ServiceEndpointList><Endpoint transportProfile=\"bdxr-transport-ebms3-as4-v1p0\"><EndpointURI>http://localhost:8080/domibus-weblogic/services/msh</EndpointURI><RequireBusinessLevelSignature>true</RequireBusinessLevelSignature><ServiceActivationDate>2003-01-01T00:00:00</ServiceActivationDate><ServiceExpirationDate>2099-05-01T00:00:00</ServiceExpirationDate>" +
             "<Certificate>VGhpcyBpcyB0ZXN0IGNlcnRpZmljYXRlIGlzIHlvdSBiZWxpZXZlIG9yIG5vdC4=</Certificate><ServiceDescription>Sample description of %s</ServiceDescription><TechnicalContactUrl>https://example.com</TechnicalContactUrl></Endpoint></ServiceEndpointList></Process></ProcessList></ServiceInformation></ServiceMetadata>";
 
     public static final String SIMPLE_REDIRECT_DOCUMENT_XML ="<ServiceMetadata xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\">" +
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java
index 0ba18573bcf0992ecc7e49abaec8d8a16a52f620..d5c888ea4861a8ea019d6c156f7526474333ef91 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java
@@ -107,10 +107,10 @@ public class TestDBUtils {
         DBUser dbuser = new DBUser();
         dbuser.setUsername(userName);
         dbuser.setRole("test");
-        dbuser.setEmailAddress("test@test.eu");
+        dbuser.setEmailAddress(userName + "@test.eu");
         dbuser.setPasswordChanged(OffsetDateTime.now());
         dbuser.setPassword(UUID.randomUUID().toString());
-        dbuser.setAccessTokenIdentifier(userName);
+        dbuser.setAccessTokenIdentifier(TOKEN_PREFIX + userName);
         dbuser.setAccessToken(UUID.randomUUID().toString());
         return dbuser;
     }
@@ -136,7 +136,7 @@ public class TestDBUtils {
     }
 
     public static DBUser createDBUserByCertificate(String certId, OffsetDateTime validFrom, OffsetDateTime validTo) {
-        return createDBUser("test-" + certId, certId, validFrom,validTo);
+        return createDBUser("test-" + certId, certId, validFrom, validTo);
     }
 
     public static DBUser createDBUser(String userName, String certId) {
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/ExtLibraryClassLoaderTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/ExtLibraryClassLoaderTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b597b97f83b1f12a1dafa52ea3f1dbcb28588ceb
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/ExtLibraryClassLoaderTest.java
@@ -0,0 +1,32 @@
+package eu.europa.ec.edelivery.smp.utils;
+
+import org.junit.Test;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static org.junit.Assert.*;
+
+public class ExtLibraryClassLoaderTest {
+
+    @Test
+    public void discoverLibraries() throws MalformedURLException {
+        Path path = Paths.get("src", "test","resources","test-libs");
+        URL[] result = ExtLibraryClassLoader.discoverLibraries(path.toFile());
+        assertNotNull(result);
+        assertEquals(2, result.length);
+    }
+
+    @Test
+    public void getLibraryFolder() throws MalformedURLException {
+        Path path = Paths.get("src", "test","resources","test-libs");
+        ExtLibraryClassLoader  loader = new ExtLibraryClassLoader(path.toFile(), ClassLoader.getSystemClassLoader());
+        URL url = loader.getResource("test-load-library.xml");
+        URL urlNotExists = loader.getResource("test-load-library-notExists.xml");
+        assertEquals(path.toFile(), loader.getLibraryFolder());
+        assertNotNull(url);
+        assertNull(urlNotExists);
+    }
+}
\ No newline at end of file
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/HttpForwardedHeadersTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/HttpForwardedHeadersTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..cfeadee567824836303f258bf9a247ad719fe053
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/HttpForwardedHeadersTest.java
@@ -0,0 +1,76 @@
+package eu.europa.ec.edelivery.smp.utils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mockito.Mockito;
+import org.springframework.http.HttpMethod;
+
+import javax.servlet.http.HttpServletRequest;
+
+import java.util.Collection;
+import java.util.List;
+
+import static eu.europa.ec.edelivery.smp.utils.HttpForwardedHeaders.ForwardedHeaderNameEnum.*;
+import static java.util.Arrays.asList;
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Parameterized.class)
+public class HttpForwardedHeadersTest {
+
+    @Parameterized.Parameters(name = "{index}: {0}")
+    public static Collection cookieWriterTestParameters() {
+        return asList(new Object[][]{
+                {"test-host", "8181","http","172.1.0.1",  "test-host", "8181", "8181", "http","172.1.0.1"},
+                {"NormaLIZE-hOst", "8181","http","172.1.0.1",  "normalize-host", "8181", "8181", "http","172.1.0.1"},
+                {"default-http", "80","http","172.1.0.1",  "default-http", "80", null, "http","172.1.0.1"},
+                {"default-https", "443","https","172.1.0.1",  "default-https", "443", null, "https","172.1.0.1"},
+                {"https-host", "8443","https","172.1.0.1",  "https-host", "8443", "8443", "https","172.1.0.1"},
+                {"normalize-scheme", "8443","hTTps","172.1.0.1",  "normalize-scheme", "8443", "8443", "https","172.1.0.1"},
+                {"host-port:773", null,"https","172.1.0.1",  "host-port", "773", "773", "https","172.1.0.1"},
+                {"host-port-equal:773", "773","https","172.1.0.1",  "host-port-equal", "773", "773", "https","172.1.0.1"},
+                {"header-port-priority:773", "8843","https","172.1.0.1",  "header-port-priority", "8843", "8843", "https","172.1.0.1"},
+        });
+    }
+
+    @Parameterized.Parameter(0)
+    public String hostName;
+    @Parameterized.Parameter(1)
+    public String port;
+    @Parameterized.Parameter(2)
+    public String scheme;
+    @Parameterized.Parameter(3)
+    public String forCall;
+    @Parameterized.Parameter(4)
+    public String resultHostName;
+    @Parameterized.Parameter(5)
+    public String resultPort;
+    @Parameterized.Parameter(6)
+    public String resultDefaultPort;
+    @Parameterized.Parameter(7)
+    public String resultScheme;
+    @Parameterized.Parameter(8)
+    public String resultForCall;
+
+
+    @Test
+    public void getReadForwardHeadersFromRequest() {
+
+
+        HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+        Mockito.doReturn(hostName).when(request).getHeader(HOST.getHeaderName());
+        Mockito.doReturn(scheme).when(request).getHeader(PROTO.getHeaderName());
+        Mockito.doReturn(forCall).when(request).getHeader(FOR.getHeaderName());
+        Mockito.doReturn(port).when(request).getHeader(PORT.getHeaderName());
+
+        HttpForwardedHeaders testInstance = new HttpForwardedHeaders(request);
+
+        assertEquals(resultHostName, testInstance.getHost());
+        assertEquals(resultPort, testInstance.getPort());
+        assertEquals(resultDefaultPort, testInstance.getNonDefaultPort());
+        assertEquals(resultScheme, testInstance.getProto());
+        assertEquals(resultForCall, testInstance.getForClientHost());
+
+    }
+
+}
\ No newline at end of file
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/PropertyUtilsTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/PropertyUtilsTest.java
index 2a44831d7302b546788becc9151d88b89cf11540..9f689426eff1206df46a02b3987f85c956dfc4a4 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/PropertyUtilsTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/PropertyUtilsTest.java
@@ -10,6 +10,8 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.io.File;
+import java.nio.file.Paths;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.regex.Pattern;
@@ -21,23 +23,34 @@ import static org.junit.Assert.*;
 @RunWith(JUnitParamsRunner.class)
 public class PropertyUtilsTest {
 
+
+    private static final List<SMPPropertyEnum> SENSITIVE_PROPERTIES = Arrays.asList(
+            HTTP_PROXY_PASSWORD,
+            KEYSTORE_PASSWORD,
+            TRUSTSTORE_PASSWORD,
+            KEYSTORE_PASSWORD_DECRYPTED,
+            TRUSTSTORE_PASSWORD_DECRYPTED,
+            MAIL_SERVER_PASSWORD);
+    private static final File ROOT_FOLDER = Paths.get("target").toFile();
+
+
     private static final Object[] testTypeValues() {
         return new Object[][]{
-                {STRING, "this is a string", true, true},
-                {INTEGER, "1345", true, true},
-                {INTEGER, " 1e345", false, false},
-                {BOOLEAN, "true", true, true},
-                {BOOLEAN, "false", true, true},
-                {BOOLEAN, "fALse", true, true},
-                {BOOLEAN, "fale ", false, true},
-                {REGEXP, ".*", true, true},
-                {REGEXP, ".*(**]", false, false},
-                {EMAIL, "test@mail.com", true, true},
-                {EMAIL, "test@2222.comsfs", false, false},
-                {EMAIL, "test@coms.fs", false, false},
-                {FILENAME, "myfilename.txt", true, true},
-                {PATH, "./", true, true},
-                {PATH, "./notexits", true, true}, // path will be created
+                {STRING, "this is a string", true},
+                {INTEGER, "1345", true},
+                {INTEGER, " 1e345", false},
+                {BOOLEAN, "true", true},
+                {BOOLEAN, "false", true},
+                {BOOLEAN, "fALse", true},
+                {BOOLEAN, "fale ", false},
+                {REGEXP, ".*", true},
+                {REGEXP, ".*(**]", false},
+                {EMAIL, "test@mail.com", true},
+                {EMAIL, "test@2222.comsfs", false},
+                {EMAIL, "test@coms.fs", false},
+                {FILENAME, "myfilename.txt", true},
+                {PATH, "./", true},
+                {PATH, "./notexits", true}, // path will be created
         };
     }
 
@@ -75,20 +88,17 @@ public class PropertyUtilsTest {
     @Test
     @Parameters(method = "testParsePropertiesToType")
     public void testParsePropertiesToType(SMPPropertyEnum property, String value, Class cls) {
-        // given
-        File folder = new File("./target");
         //when then
-        Object obj = PropertyUtils.parseProperty(property, value, folder);
+        Object obj = PropertyUtils.parseProperty(property, value, ROOT_FOLDER);
         Assert.assertTrue(cls.isInstance(obj));
 
     }
 
     @Test
     @Parameters(method = "testTypeValues")
-    public void testIsValidPropertyType(SMPPropertyTypeEnum propertyType, String value, boolean expected,
-                                        boolean isNotNull) {
+    public void testIsValidPropertyType(SMPPropertyTypeEnum propertyType, String value, boolean expected) {
         //when
-        boolean result = PropertyUtils.isValidPropertyType(propertyType, value);
+        boolean result = PropertyUtils.isValidPropertyType(propertyType, value, ROOT_FOLDER);
 
         //then
         assertEquals(expected, result);
@@ -99,14 +109,15 @@ public class PropertyUtilsTest {
     public void testDefaultValues() {
 
         for (SMPPropertyEnum prop : SMPPropertyEnum.values()) {
-            assertTrue("Invalid: " + prop.getProperty() + " - " + prop.getDesc() + " value: " + prop.getDefValue(), PropertyUtils.isValidProperty(prop, prop.getDefValue()));
+            assertTrue( PropertyUtils.isValidProperty(prop, prop.getDefValue(), ROOT_FOLDER));
         }
     }
 
     @Test
     public void testParseDefaultValues() {
+
         for (SMPPropertyEnum prop : SMPPropertyEnum.values()) {
-            Object obj = PropertyUtils.parseProperty(prop, prop.getDefValue(), null);
+            Object obj = PropertyUtils.parseProperty(prop, prop.getDefValue(), ROOT_FOLDER);
             assertType(prop, obj);
         }
     }
@@ -114,31 +125,19 @@ public class PropertyUtilsTest {
 
     @Test
     @Parameters(method = "testTypeValues")
-    public void testParsePropertyType(SMPPropertyTypeEnum propertyType, String value, boolean isValid,
-                                      boolean isNotNull) {
-        // given
-        File folder = new File("./target");
-        //when then
-        Object obj = null;
-        try {
-            obj = PropertyUtils.parsePropertyType(propertyType, value, folder);
-            assertTrue(isNotNull);
-            assertNotNull(obj);
-        } catch (SMPRuntimeException ex) {
-            assertFalse(isNotNull);
-            assertNull(obj);
+    public void testParsePropertyType(SMPPropertyTypeEnum propertyType, String value, boolean expectParseOk) {
+        if (expectParseOk) {
+            Object result = PropertyUtils.parsePropertyType(propertyType, value, ROOT_FOLDER);
+            assertNotNull(result);
+            assertType(propertyType, result);
         }
-    }
-
-
-    public static void assertType(SMPPropertyEnum prop, Object value) {
-        if (value == null) {
-            if (prop.isMandatory()) {
-                Assert.fail("Default value for property: " + prop.getProperty() + " must not be empty!");
-            }
-            return;
+        else {
+            SMPRuntimeException exception = assertThrows(SMPRuntimeException.class, ()->PropertyUtils.parsePropertyType(propertyType, value, ROOT_FOLDER));
+            assertNotNull(exception.getErrorCode());
         }
-        switch (prop.getPropertyType()) {
+    }
+    public static void assertType(SMPPropertyTypeEnum prop, Object value) {
+        switch (prop) {
             case BOOLEAN:
                 Assert.assertEquals(Boolean.class, value.getClass());
                 break;
@@ -171,4 +170,30 @@ public class PropertyUtilsTest {
                 fail("Unknown property type");
         }
     }
+
+    public static void assertType(SMPPropertyEnum prop, Object value) {
+        if (value == null) {
+            if (prop.isMandatory()) {
+                Assert.fail("Default value for property: " + prop.getProperty() + " must not be empty!");
+            }
+            return;
+        }
+        assertType(prop.getPropertyType(), value);
+    }
+
+    @Test
+    public void testIsSensitiveData() {
+        for (SMPPropertyEnum smpPropertyEnum: SMPPropertyEnum.values()){
+            Assert.assertEquals(SENSITIVE_PROPERTIES.contains(smpPropertyEnum), PropertyUtils.isSensitiveData(smpPropertyEnum.getProperty()));
+        }
+    }
+
+    @Test
+    public void getMaskedData() {
+        String testValue = "TestValue";
+        for (SMPPropertyEnum smpPropertyEnum: SMPPropertyEnum.values()){
+            String expectedValue = SENSITIVE_PROPERTIES.contains(smpPropertyEnum)?"*******":testValue;
+            Assert.assertEquals(expectedValue, PropertyUtils.getMaskedData(smpPropertyEnum.getProperty(),testValue));
+        }
+    }
 }
\ No newline at end of file
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/SecurityUtilsTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/SecurityUtilsTest.java
index a4e500a893789b3e4f22c04090f90c65e074839c..03e4381cc2a72500be25b551cee04e8a76024508 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/SecurityUtilsTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/SecurityUtilsTest.java
@@ -52,7 +52,7 @@ public class SecurityUtilsTest {
     @Test
     public void testGenerateAccessToken(){
         // given-when
-        AccessTokenRO accessToken = SecurityUtils.generateAccessToken();
+        AccessTokenRO accessToken = SecurityUtils.generateAccessToken(true);
         // then
         assertNotNull(accessToken);
         assertNotNull(accessToken.getGeneratedOn());
diff --git a/smp-server-library/src/test/resources/config.properties b/smp-server-library/src/test/resources/config.properties
index c90e33adec0c4fcd58db89190011fc4e0f73bbc5..5c4f05199fb155a1334eb8c3723be14379f3de00 100644
--- a/smp-server-library/src/test/resources/config.properties
+++ b/smp-server-library/src/test/resources/config.properties
@@ -42,6 +42,7 @@ xmldsig.keystore.password     = mock
 ##jdbc.read-connections.max = ${jdbc.read-connections.max}
 
 
+test.read.property=This property is from fallback legacy file
 # Used by FileConfig tests:
 
 element1=string
diff --git a/smp-server-library/src/test/resources/create-configuration-table-h2.ddl b/smp-server-library/src/test/resources/create-configuration-table-h2.ddl
new file mode 100644
index 0000000000000000000000000000000000000000..89c3f584562712a5ea73947598a85662e8d6ca7f
--- /dev/null
+++ b/smp-server-library/src/test/resources/create-configuration-table-h2.ddl
@@ -0,0 +1,26 @@
+create table SMP_CONFIGURATION (
+   PROPERTY varchar(512) not null,
+    CREATED_ON timestamp not null,
+    LAST_UPDATED_ON timestamp not null,
+    DESCRIPTION varchar(4000),
+    VALUE varchar(4000),
+    primary key (PROPERTY)
+);
+create table SMP_CONFIGURATION_AUD (
+   PROPERTY varchar(512) not null,
+    REV bigint not null,
+    REVTYPE tinyint,
+    CREATED_ON timestamp,
+    LAST_UPDATED_ON timestamp,
+    DESCRIPTION varchar(4000),
+    VALUE varchar(4000),
+    primary key (PROPERTY, REV)
+);
+
+create table SMP_REV_INFO (
+   id bigint generated by default as identity,
+    REVISION_DATE timestamp,
+    timestamp bigint not null,
+    USERNAME varchar(255),
+    primary key (id)
+);
\ No newline at end of file
diff --git a/smp-server-library/src/test/resources/test-libs/simple-extension-01.jar b/smp-server-library/src/test/resources/test-libs/simple-extension-01.jar
new file mode 100644
index 0000000000000000000000000000000000000000..991ee4cc4660cb706f3ef484d25a4a11132584ab
Binary files /dev/null and b/smp-server-library/src/test/resources/test-libs/simple-extension-01.jar differ
diff --git a/smp-server-library/src/test/resources/test-libs/simple-extension-02.jar b/smp-server-library/src/test/resources/test-libs/simple-extension-02.jar
new file mode 100644
index 0000000000000000000000000000000000000000..cd54a5d9adc661fa9ebf6fc01243eaad123aac7a
Binary files /dev/null and b/smp-server-library/src/test/resources/test-libs/simple-extension-02.jar differ
diff --git a/smp-server-library/src/test/resources/test-smp.config.properties b/smp-server-library/src/test/resources/test-smp.config.properties
new file mode 100644
index 0000000000000000000000000000000000000000..68119a8e20ba824807290023701c0b1cd47dd12a
--- /dev/null
+++ b/smp-server-library/src/test/resources/test-smp.config.properties
@@ -0,0 +1,6 @@
+# JDBC configuration for DB
+jdbc.driver = com.mysql.jdbc.Driver
+jdbc.url = jdbc:mysql://localhost:3306/smp
+jdbc.user = smp-test-read-prop
+jdbc.password=****
+test.read.property=This property is from custom file
\ No newline at end of file
diff --git a/smp-soapui-tests/groovy/mysql-4.1_integration_test_data.sql b/smp-soapui-tests/groovy/mysql-4.1_integration_test_data.sql
index b2cf07e7fb3fbc086cc8cbca5f604e40625d6ee7..669cadf52f0e7446f4a2abb6bd6bf8d5893ee786 100644
--- a/smp-soapui-tests/groovy/mysql-4.1_integration_test_data.sql
+++ b/smp-soapui-tests/groovy/mysql-4.1_integration_test_data.sql
@@ -1,51 +1,51 @@
-insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (1, 'peppol_user', '$2a$10$.pqNZZ4fRDdNbLhNlnEYg.1/d4yAGpLDgeXpJFI0sw7.WtyKphFzu','peppol_user', '$2a$10$.pqNZZ4fRDdNbLhNlnEYg.1/d4yAGpLDgeXpJFI0sw7.WtyKphFzu', 'SMP_ADMIN', 1, NOW(), NOW());
-insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (2, 'the_admin', '','the_admin', '', 'SMP_ADMIN', 1, NOW(), NOW());
-insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (3, 'AdminSMP1TEST', '$2a$06$u6Hym7Zrbsf4gEIeAsJRceK.Kg7tei3kDypwucQQdky0lXOLCkrCO','AdminSMP1TEST', '$2a$06$u6Hym7Zrbsf4gEIeAsJRceK.Kg7tei3kDypwucQQdky0lXOLCkrCO', 'SMP_ADMIN', 1, NOW(), NOW());
-insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (4, 'AdminSMP2TEST', '$2a$10$h8Q3Kjbs6ZrGkU6ditjNueINlJOMDJ/g/OKiqFZy32WmdhLjV5TAi','AdminSMP2TEST', '$2a$10$h8Q3Kjbs6ZrGkU6ditjNueINlJOMDJ/g/OKiqFZy32WmdhLjV5TAi', 'SMP_ADMIN', 1, NOW(), NOW());
-insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (5, 'test', '','test', '',  'SMP_ADMIN', 1, NOW(), NOW());
-insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (6, 'test1', '$2a$06$toKXJgjqQINZdjQqSao3NeWz2n1S64PFPhVU1e8gIHh4xdbwzy1Uy','test1', '$2a$06$toKXJgjqQINZdjQqSao3NeWz2n1S64PFPhVU1e8gIHh4xdbwzy1Uy', 'SMP_ADMIN', 1, NOW(), NOW());
-insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (7, 'system', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36','system', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36', 'SYSTEM_ADMIN', 1, NOW(), NOW());
-insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (8, 'smp', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36','smp', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36', 'SMP_ADMIN', 1, NOW(), NOW());
-insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (9, 'user', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36','user', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36', 'SERVICE_GROUP_ADMIN', 1, NOW(), NOW());
-
-
-insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (10, 'EHEALTH_SMP_EC', '', 'SERVICE_GROUP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (1, 'peppol_user@test-mail.eu','peppol_user', '$2a$10$.pqNZZ4fRDdNbLhNlnEYg.1/d4yAGpLDgeXpJFI0sw7.WtyKphFzu','peppol_user', '$2a$10$.pqNZZ4fRDdNbLhNlnEYg.1/d4yAGpLDgeXpJFI0sw7.WtyKphFzu', 'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (2, 'the_admin@test-mail.eu','the_admin', '','the_admin', '', 'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (3, 'AdminSMP1TEST@test-mail.eu','AdminSMP1TEST', '$2a$06$u6Hym7Zrbsf4gEIeAsJRceK.Kg7tei3kDypwucQQdky0lXOLCkrCO','AdminSMP1TEST', '$2a$06$u6Hym7Zrbsf4gEIeAsJRceK.Kg7tei3kDypwucQQdky0lXOLCkrCO', 'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (4, 'AdminSMP2TEST@test-mail.eu','AdminSMP2TEST', '$2a$10$h8Q3Kjbs6ZrGkU6ditjNueINlJOMDJ/g/OKiqFZy32WmdhLjV5TAi','AdminSMP2TEST', '$2a$10$h8Q3Kjbs6ZrGkU6ditjNueINlJOMDJ/g/OKiqFZy32WmdhLjV5TAi', 'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (5, 'test@test-mail.eu','test', '','test', '',  'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (6, 'test1@test-mail.eu','test1', '$2a$06$toKXJgjqQINZdjQqSao3NeWz2n1S64PFPhVU1e8gIHh4xdbwzy1Uy','test1', '$2a$06$toKXJgjqQINZdjQqSao3NeWz2n1S64PFPhVU1e8gIHh4xdbwzy1Uy', 'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (7, 'system@test-mail.eu','system', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36','system', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36', 'SYSTEM_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (8, 'smp@test-mail.eu','smp', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36','smp', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36', 'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (9, 'user@test-mail.eu','user', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36','user', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36', 'SERVICE_GROUP_ADMIN', 1, NOW(), NOW());
+
+
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (10,'EHEALTH_SMP_EC@test-mail.eu', 'EHEALTH_SMP_EC', '', 'SERVICE_GROUP_ADMIN', 1, NOW(), NOW());
 insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (10, 'CN=EHEALTH_SMP_EC,O=European Commission,C=BE:f71ee8b11cb3b787', date_add(NOW(),interval -1 year), date_add(NOW(),interval 1 year), NOW(), NOW());
 
-insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (11, 'EHEALTH_ż_ẞ_Ẅ_,O', '', 'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (11,'EHEALTH_z_ẞ_W@test-mail.eu', 'EHEALTH_ż_ẞ_Ẅ_,O', '', 'SMP_ADMIN', 1, NOW(), NOW());
 insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (11, 'CN=EHEALTH_z_ẞ_W_,O=European_z_ẞ_W_Commission,C=BE:f71ee8b11cb3b787', null,null, NOW(), NOW());
 
-insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (12, 'EHEALTH_SMP_1000000007-1', '', 'SERVICE_GROUP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (12,'EHEALTH_SMP_1000000007-1@test-mail.eu', 'EHEALTH_SMP_1000000007-1', '', 'SERVICE_GROUP_ADMIN', 1, NOW(), NOW());
 insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (12, 'CN=EHEALTH_SMP_1000000007,O=DG-DIGIT,C=BE:000000000123ABCD', null,null, NOW(), NOW());
 
 
-insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (14, 'EHEALTH_SMP_1000000007-2', '', 'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (14,'EHEALTH_SMP_1000000007-2@test-mail.eu', 'EHEALTH_SMP_1000000007-2', '', 'SMP_ADMIN', 1, NOW(), NOW());
 insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (14, 'CN=EHEALTH_SMP_1000000007,O=DG-DIGIT,C=BE', null,null, NOW(), NOW());
 
-insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (15, 'EHEALTH&SMP_EC', '', 'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (15,'EHEALTH-SMP_EC@test-mail.eu', 'EHEALTH&SMP_EC', '', 'SMP_ADMIN', 1, NOW(), NOW());
 insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (15, 'CN=EHEALTH&SMP_EC,O=European&Commission,C=B&E:f71ee8b11cb3b787', null,null, NOW(), NOW());
 
-insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (16, 'EHEALTH_SMP_EC2', '', 'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (16,'EHEALTH_SMP_EC2@test-mail.eu', 'EHEALTH_SMP_EC2', '', 'SMP_ADMIN', 1, NOW(), NOW());
 insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (16, 'CN=EHEALTH_SMP_EC,O=European Commission,C=BE:000000000000100f', null,null, NOW(), NOW());
 
-insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (17, 'SMP_1000000007-3', '', 'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (17,'SMP_1000000007-3@test-mail.eu', 'SMP_1000000007-3', '', 'SMP_ADMIN', 1, NOW(), NOW());
 insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (17, 'CN=SMP_1000000007,O=DG-DIGIT,C=BE', null,null, NOW(), NOW());
 
-insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (18, 'SMP_1000000007-4', '', 'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (18,'SMP_1000000007-4@test-mail.eu', 'SMP_1000000007-4', '', 'SMP_ADMIN', 1, NOW(), NOW());
 insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (18, 'CN=SMP_1000000007,O=DG-DIGIT,C=BE:000000000123ABCD', null,null, NOW(), NOW());
 
-insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (19, 'SMP_1000000181,O=DIGIT,C=DK:123456789', '$2a$10$v2d/2E99dWHBM2ipTIip1enyaRKBTi.Xj/Iz0K8g0gjHBWdKRsHaC', 'SMP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (19,'SMP_1000000181@test-mail.eu', 'SMP_1000000181,O=DIGIT,C=DK:123456789', '$2a$10$v2d/2E99dWHBM2ipTIip1enyaRKBTi.Xj/Iz0K8g0gjHBWdKRsHaC', 'SMP_ADMIN', 1, NOW(), NOW());
 insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (19, 'CN=SMP_1000000181,O=DIGIT,C=DK:123456789', null,null, NOW(), NOW());
 
-insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (20, 'red_gw', '', 'SERVICE_GROUP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (20,'red_gw@test-mail.eu', 'red_gw', '', 'SERVICE_GROUP_ADMIN', 1, NOW(), NOW());
 insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (20, 'CN=red_gw,O=eDelivery,C=BE:9792CE69BC89F14C', null,null, NOW(), NOW());
 
-insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (21, 'blue_gw', '', 'SERVICE_GROUP_ADMIN', 1, NOW(), NOW());
+insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (21,'blue_gw@test-mail.eu', 'blue_gw', '', 'SERVICE_GROUP_ADMIN', 1, NOW(), NOW());
 insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (21, 'CN=blue_gw,O=eDelivery,C=BE:e07b6b956330a19a', null,null, NOW(), NOW());
 
 -- insert domain
 insert into SMP_DOMAIN (ID, DOMAIN_CODE, SML_SUBDOMAIN, SML_SMP_ID, SIGNATURE_KEY_ALIAS, SML_CLIENT_KEY_ALIAS, SML_BLUE_COAT_AUTH,SML_REGISTERED, CREATED_ON, LAST_UPDATED_ON, SML_CLIENT_CERT_HEADER)
-values (1, 'domain','','CEF-SMP-002', 'sample_key','sample_key', 1,0, NOW(), NOW(),'sno=1&subject=CN=SMP_TEST-PRE-SET-EXAMPLE, OU=eDelivery, O=DIGITAL, C=BE&validfrom=Dec 6 17:41:42 2016 GMT&validto=Jul 9 23:59:00 2050 GMT&issuer=CN=rootCNTest,OU=B4,O=DIGIT,L=Brussels,ST=BE,C=BE');
+values (1, 'domain','','CEF-SMP-001', 'sample_key','sample_key', 1,1, NOW(), NOW(),'sno=1&subject=CN=SMP_TEST-PRE-SET-EXAMPLE, OU=eDelivery, O=DIGITAL, C=BE&validfrom=Dec 6 17:41:42 2016 GMT&validto=Jul 9 23:59:00 2050 GMT&issuer=CN=rootCNTest,OU=B4,O=DIGIT,L=Brussels,ST=BE,C=BE');
 
 insert into SMP_DOMAIN (ID, DOMAIN_CODE, SML_SUBDOMAIN, SML_SMP_ID, SIGNATURE_KEY_ALIAS, SML_BLUE_COAT_AUTH,SML_REGISTERED, CREATED_ON, LAST_UPDATED_ON) values (2, 'domainB','subdomain002', 'CEF-SMP-002','sample_key',1,0, CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP());
 insert into SMP_DOMAIN (ID, DOMAIN_CODE, SML_SUBDOMAIN, SML_SMP_ID, SIGNATURE_KEY_ALIAS, SML_BLUE_COAT_AUTH,SML_REGISTERED, CREATED_ON, LAST_UPDATED_ON) values (3, 'domainC','subdomain003', 'CEF-SMP-003','sample_key',1,0, CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP());
diff --git a/smp-soapui-tests/pom.xml b/smp-soapui-tests/pom.xml
index f85a1dbf5774dceb2abb755c755e8919a0c39327..aa9a0be65dbfb66452f59853685c62c5ecf40e4c 100644
--- a/smp-soapui-tests/pom.xml
+++ b/smp-soapui-tests/pom.xml
@@ -18,6 +18,7 @@
         <SMPAdminUser></SMPAdminUser>
         <SMPAdminPassword></SMPAdminPassword>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
     </properties>
 
     <profiles>
@@ -111,27 +112,15 @@
                             </execution>
                         </executions>
                     </plugin>
-                    <!-- dump jacoco.exec from remote agent and generate report  -->
+                    <!-- dump jacoco report from remote agent and generate report  -->
                     <plugin>
                         <groupId>org.jacoco</groupId>
                         <artifactId>jacoco-maven-plugin</artifactId>
                         <version>${jacoco.maven.plugin.version}</version>
                         <configuration>
-                            <classDumpDir>${project.build.outputDirectory}</classDumpDir>
+                            <classDumpDir>${project.build.outputDirectory}../target/</classDumpDir>
                         </configuration>
                         <executions>
-                            <!-- execution>
-                                <id>jacoco-agent</id>
-                                <phase>pre-integration-test</phase>
-                                <goals>
-                                    <goal>prepare-agent</goal>
-                                </goals>
-                                <configuration>
-                                    <destFile>${jacoco.reportPath}</destFile>
-                                    <propertyName>jacoco.agent.itArgLine</propertyName>
-                                </configuration>
-                            </execution -->
-
                             <execution>
                                 <phase>post-integration-test</phase>
                                 <goals>
diff --git a/smp-spi/pom.xml b/smp-spi/pom.xml
index ead4a25ebaf238872c2df608177fc60f3b7ad327..d626978bb7f52e8bb27cf8928adb5cc59651b016 100644
--- a/smp-spi/pom.xml
+++ b/smp-spi/pom.xml
@@ -20,25 +20,16 @@
         <version>4.2-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
-
     <artifactId>smp-spi</artifactId>
     <name>smp-spi</name>
     <description>SMP Service provider interface (SPI). The SMP SPI is an application interface intended to be implemented or extended
         by a third party as library. The libraries must be added to SMP library directory and are loaded at startup.</description>
+    <packaging>jar</packaging>
     <dependencies>
-        <dependency>
-            <groupId>ch.qos.logback</groupId>
-            <artifactId>logback-classic</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-junit</artifactId>
-            <scope>test</scope>
-        </dependency>
     </dependencies>
     <build>
         <plugins>
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SMPInitializer.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SMPInitializer.java
index 8a6e92192f70c44d7e8f443e80cce6516f55d2e4..a104ac0f3ae558ef0d9ba2bdd47711cd0d357dcd 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SMPInitializer.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SMPInitializer.java
@@ -1,49 +1,43 @@
 package eu.europa.ec.edelivery.smp.config;
 
-import eu.europa.ec.edelivery.smp.auth.URLCsrfIgnoreMatcher;
-import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
-import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.utils.ExtLibraryClassLoader;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.commons.text.StringSubstitutor;
 import org.slf4j.Logger;
 import org.springframework.web.WebApplicationInitializer;
 
 import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.util.Properties;
 
-import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.CONFIGURATION_DIR;
-
 
 public class SMPInitializer implements WebApplicationInitializer {
 
     private static final String FILE_APPLICATION_PROPERTIES = "/application.properties";
 
-    private static final String PROP_BUILD_NAME = "smp.artifact.name";
-    private static final String PROP_BUILD_VERSION = "smp.artifact.version";
-    private static final String PROP_BUILD_TIME = "smp.artifact.build.time";
+    protected static final String PROP_BUILD_NAME = "smp.artifact.name";
+    protected static final String PROP_BUILD_VERSION = "smp.artifact.version";
+    protected static final String PROP_BUILD_TIME = "smp.artifact.build.time";
+    protected static final String VERSION_LOG_TEMPLATE = "Start application: name: {}, version: {}, build time: {}.";
+
 
+    private static final Logger LOG = SMPLoggerFactory.getLogger(SMPInitializer.class);
 
-    private static final Logger LOG = SMPLoggerFactory.getLogger(
-            SMPInitializer.class);
     @Override
-    public void onStartup(ServletContext servletContext) throws ServletException {
+    public void onStartup(ServletContext servletContext) {
         Properties fileProperties = FileProperty.getFileProperties();
-        logBuildProperties();
+        logBuildProperties(LOG, FILE_APPLICATION_PROPERTIES);
 
         // load external libraries
         String libraryFolderPath = StringUtils.trim(fileProperties.getProperty(FileProperty.PROPERTY_LIB_FOLDER, null));
-        if (StringUtils.isNotBlank(libraryFolderPath)){
+        if (StringUtils.isNotBlank(libraryFolderPath)) {
             File fLibraryDir = new File(libraryFolderPath);
             ExtLibraryClassLoader pluginClassLoader = createLibraryClassLoader(fLibraryDir);
-            if (pluginClassLoader!=null){
+            if (pluginClassLoader != null) {
                 LOG.debug("Add libraries from the folder: [{}]!", libraryFolderPath);
                 Thread.currentThread().setContextClassLoader(pluginClassLoader);
             }
@@ -55,22 +49,22 @@ public class SMPInitializer implements WebApplicationInitializer {
     /**
      * Method reads internal 'application.properties' file and prints the build version to the logs
      */
-    protected void logBuildProperties() {
-        InputStream is = PropertyInitialization.class.getResourceAsStream(FILE_APPLICATION_PROPERTIES);
+    protected void logBuildProperties(Logger log, String versionResource) {
+        InputStream is = SMPInitializer.class.getResourceAsStream(versionResource);
         if (is != null) {
             Properties applProp = new Properties();
             try {
                 applProp.load(is);
-                LOG.info("*****************************************************************************************");
-                LOG.info("Start application: name: {}, version: {}, build time: {}.", applProp.getProperty(PROP_BUILD_NAME)
+                log.info("*****************************************************************************************");
+                log.info(VERSION_LOG_TEMPLATE, applProp.getProperty(PROP_BUILD_NAME)
                         , applProp.getProperty(PROP_BUILD_VERSION)
                         , applProp.getProperty(PROP_BUILD_TIME));
-                LOG.info("*****************************************************************************************");
+                log.info("*****************************************************************************************");
             } catch (IOException e) {
-                LOG.error("Error occurred  while reading application properties. Is file " + FILE_APPLICATION_PROPERTIES + " included in war!", e);
+                log.error("Error occurred  while reading application properties. Is file " + FILE_APPLICATION_PROPERTIES + " included in war!", e);
             }
         } else {
-            LOG.error("Not found application build properties: {}!", FILE_APPLICATION_PROPERTIES);
+            log.error("Not found application build properties: {}!", FILE_APPLICATION_PROPERTIES);
         }
     }
 
@@ -82,11 +76,11 @@ public class SMPInitializer implements WebApplicationInitializer {
      */
     protected ExtLibraryClassLoader createLibraryClassLoader(File smpLibraryFolder) {
         LOG.info("Load libraries from location [{}]", smpLibraryFolder);
-        if (!smpLibraryFolder.exists() ) {
+        if (!smpLibraryFolder.exists()) {
             LOG.warn("Library folder [{}] does not exist! No libraries are loaded!", smpLibraryFolder.getAbsolutePath());
             return null;
         }
-        if (!smpLibraryFolder.isDirectory() ) {
+        if (!smpLibraryFolder.isDirectory()) {
             LOG.warn("Library folder [{}] is not a folder! No libraries are loaded!", smpLibraryFolder.getAbsolutePath());
             return null;
         }
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/PropertyResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/PropertyResource.java
index 3b042080805e1cf844cb50d48fcbebb66a9c5608..cd0f3265992c580cfe25731bc47721682e41d1c0 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/PropertyResource.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/PropertyResource.java
@@ -2,11 +2,12 @@ package eu.europa.ec.edelivery.smp.ui.internal;
 
 
 import eu.europa.ec.edelivery.smp.data.ui.PropertyRO;
+import eu.europa.ec.edelivery.smp.data.ui.PropertyValidationRO;
 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.auth.SMPAuthority;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
+import eu.europa.ec.edelivery.smp.services.ConfigurationService;
 import eu.europa.ec.edelivery.smp.services.ui.UIPropertyService;
 import org.springframework.security.access.annotation.Secured;
 import org.springframework.util.MimeTypeUtils;
@@ -27,13 +28,15 @@ public class PropertyResource {
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(PropertyResource.class);
 
     final UIPropertyService uiPropertyService;
+    final ConfigurationService configurationService;
 
-    public PropertyResource(UIPropertyService uiPropertyService) {
+    public PropertyResource(UIPropertyService uiPropertyService, ConfigurationService configurationService) {
         this.uiPropertyService = uiPropertyService;
+        this.configurationService = configurationService;
     }
 
     @GetMapping(produces = {MimeTypeUtils.APPLICATION_JSON_VALUE})
-    public ServiceResult<PropertyRO> geDomainList(
+    public ServiceResult<PropertyRO> gePropertyList(
             @RequestParam(value = PARAM_PAGINATION_PAGE, defaultValue = "0") int page,
             @RequestParam(value = PARAM_PAGINATION_PAGE_SIZE, defaultValue = "10") int pageSize,
             @RequestParam(value = PARAM_PAGINATION_ORDER_BY, required = false) String orderBy,
@@ -52,4 +55,11 @@ public class PropertyResource {
         uiPropertyService.updatePropertyList(Arrays.asList(updateEntities));
     }
 
+    @PostMapping(path = "/validate", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+    @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN})
+    public PropertyValidationRO validateProperty(@RequestBody PropertyRO propertyRO) {
+        LOG.info("Validate property: [{}]", propertyRO.getProperty());
+        return uiPropertyService.validateProperty(propertyRO);
+    }
+
 }
diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/config/SMPInitializerTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/config/SMPInitializerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..999439ff6fe87ec2038e51c63af65b2371ae5658
--- /dev/null
+++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/config/SMPInitializerTest.java
@@ -0,0 +1,64 @@
+package eu.europa.ec.edelivery.smp.config;
+
+import eu.europa.ec.edelivery.smp.utils.ExtLibraryClassLoader;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+import org.slf4j.Logger;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static org.junit.Assert.*;
+
+public class SMPInitializerTest {
+
+    SMPInitializer testInstance = new SMPInitializer();
+    @Test
+    public void onStartup() {
+    }
+
+    @Test
+    public void logBuildProperties() {
+        Logger log = Mockito.mock(Logger.class);
+        testInstance.logBuildProperties(log, "/test-application.properties");
+
+        ArgumentCaptor<String> template = ArgumentCaptor.forClass(String.class);
+        ArgumentCaptor<String> name = ArgumentCaptor.forClass(String.class);
+        ArgumentCaptor<String> version = ArgumentCaptor.forClass(String.class);
+        ArgumentCaptor<String> date = ArgumentCaptor.forClass(String.class);
+
+        Mockito.verify(log, Mockito.times(2)).info(Mockito.anyString());
+        Mockito.verify(log, Mockito.times(1)).info(template.capture(),
+                name.capture(),
+                version.capture(),
+                date.capture() );
+
+        assertEquals(SMPInitializer.VERSION_LOG_TEMPLATE, template.getValue());
+        assertEquals("eDelivery test SMP", name.getValue());
+        assertEquals("1.0", version.getValue());
+        assertEquals("2022-05-05T12:00:00Z", date.getValue());
+    }
+
+    @Test
+    public void createLibraryClassLoaderNotExists() {
+        ExtLibraryClassLoader loader= testInstance.createLibraryClassLoader(new File("FileNotExists"));
+        assertNull(loader);
+    }
+
+    @Test
+    public void createLibraryClassLoaderIsNotFolder() {
+        ExtLibraryClassLoader loader= testInstance.createLibraryClassLoader(new File("./pom.xml"));
+        assertNull(loader);
+    }
+
+    @Test
+    public void createLibraryClassLoader() {
+        // folder contains one library jar simple-extension.jar with the resource logback-test.xml
+        Path path = Paths.get("src","test","resources", "test-libs");
+        ExtLibraryClassLoader loader= testInstance.createLibraryClassLoader(path.toFile());
+        assertNotNull(loader);
+        assertNotNull(loader.getResource("logback-test.xml"));
+    }
+}
\ No newline at end of file
diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/test/PropertiesTestConfig.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/test/PropertiesTestConfig.java
index cb762ced6b78937a68a9bc20a6622699581b892d..b649d1c9f9a6d5abb85f4308fc859b11be734d03 100644
--- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/test/PropertiesTestConfig.java
+++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/test/PropertiesTestConfig.java
@@ -13,6 +13,7 @@
 
 package eu.europa.ec.edelivery.smp.test;
 
+import eu.europa.ec.edelivery.smp.config.FileProperty;
 import eu.europa.ec.edelivery.smp.config.PropertiesConfig;
 import org.springframework.context.annotation.*;
 import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
@@ -34,17 +35,25 @@ import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.*;
                 @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = PropertiesConfig.class)})
 public class PropertiesTestConfig {
 
+    public static final String DATABASE_URL="jdbc:h2:file:./target/myDb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE;AUTO_SERVER=TRUE";
+    public static final String DATABASE_USERNAME="smp";
+    public static final String DATABASE_PASS="smp";
+    public static final String DATABASE_DRIVER="org.h2.Driver";
+    public static final String DATABASE_DIALECT="org.hibernate.dialect.H2Dialect";
+
+
     @Bean
     public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
         // update keystore
         PropertySourcesPlaceholderConfigurer propertiesConfig = new PropertySourcesPlaceholderConfigurer();
 
         Properties localProps = new Properties();
-        localProps.setProperty("jdbc.driverClassName", "org.h2.Driver");
-        localProps.setProperty("jdbc.url", "jdbc:h2:file:./target/myDb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE;AUTO_SERVER=TRUE");
-        localProps.setProperty("jdbc.user", "smp");
-        localProps.setProperty("jdbc.pass", "smp");
-        localProps.setProperty("spring.jpa.properties.hibernate.dialect", "org.hibernate.dialect.H2Dialect");
+        localProps.setProperty(FileProperty.PROPERTY_DB_DIALECT, DATABASE_DIALECT);
+        localProps.setProperty(FileProperty.PROPERTY_DB_DRIVER, DATABASE_DRIVER);
+        localProps.setProperty(FileProperty.PROPERTY_DB_URL, DATABASE_URL);
+        localProps.setProperty(FileProperty.PROPERTY_DB_USER,DATABASE_USERNAME);
+        localProps.setProperty(FileProperty.PROPERTY_DB_TOKEN, DATABASE_PASS);
+        // create database objects if not exists for the test
         localProps.setProperty("spring.jpa.generate-ddl", "true");
         localProps.setProperty("spring.jpa.properties.hibernate.hbm2ddl.auto", "create");
 
diff --git a/smp-webapp/src/test/resources/test-application.properties b/smp-webapp/src/test/resources/test-application.properties
new file mode 100644
index 0000000000000000000000000000000000000000..5d005228329b64251d810b94bca2f347bfc41e3e
--- /dev/null
+++ b/smp-webapp/src/test/resources/test-application.properties
@@ -0,0 +1,3 @@
+smp.artifact.name=eDelivery test SMP
+smp.artifact.version=1.0
+smp.artifact.build.time=2022-05-05T12:00:00Z
\ No newline at end of file
diff --git a/smp-webapp/src/test/resources/test-libs/simple-extension.jar b/smp-webapp/src/test/resources/test-libs/simple-extension.jar
new file mode 100644
index 0000000000000000000000000000000000000000..991ee4cc4660cb706f3ef484d25a4a11132584ab
Binary files /dev/null and b/smp-webapp/src/test/resources/test-libs/simple-extension.jar differ