syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From skylar...@apache.org
Subject [syncope] branch master updated: [SYNCOPE-1421] Removed old Enduser, re-built and fixed parts of the SAML and OIDC modules
Date Thu, 30 May 2019 13:17:25 GMT
This is an automated email from the ASF dual-hosted git repository.

skylark17 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new 89834fb  [SYNCOPE-1421] Removed old Enduser, re-built and fixed parts of the SAML and OIDC modules
89834fb is described below

commit 89834fbd96ef2a8262457882ed128fd8b893ac45
Author: skylark17 <matteo.alessandroni@tirasa.net>
AuthorDate: Thu May 30 15:16:46 2019 +0200

    [SYNCOPE-1421] Removed old Enduser, re-built and fixed parts of the SAML and OIDC modules
---
 client/enduser/pom.xml                             | 250 -------
 .../client/enduser/SyncopeEnduserApplication.java  |  62 --
 .../client/enduser/SyncopeEnduserSession.java      | 199 -----
 .../client/enduser/SyncopeWebApplication.java      | 384 ----------
 .../enduser/adapters/PlatformInfoAdapter.java      |  48 --
 .../client/enduser/annotations/Resource.java       |  42 --
 .../syncope/client/enduser/commons/Constants.java  |  28 -
 .../init/ClassPathScanImplementationLookup.java    |  84 ---
 .../syncope/client/enduser/model/Credentials.java  |  65 --
 .../client/enduser/model/CustomAttribute.java      |  62 --
 .../client/enduser/model/CustomAttributesInfo.java |  47 --
 .../client/enduser/model/CustomTemplate.java       |  77 --
 .../client/enduser/model/CustomTemplateInfo.java   |  72 --
 .../client/enduser/model/CustomTemplateWizard.java |  49 --
 .../client/enduser/model/PlatformInfoRequest.java  | 101 ---
 .../client/enduser/model/SchemaResponse.java       |  77 --
 .../syncope/client/enduser/pages/HomePage.java     |  56 --
 .../enduser/resources/AnyTypeClassResource.java    |  74 --
 .../client/enduser/resources/BaseResource.java     |  57 --
 .../enduser/resources/BaseUserSelfResource.java    |  82 --
 .../client/enduser/resources/CaptchaResource.java  |  56 --
 .../enduser/resources/DynamicTemplateResource.java |  79 --
 .../resources/ExternalResourceResource.java        |  83 ---
 .../client/enduser/resources/GroupResource.java    | 130 ----
 .../client/enduser/resources/InfoResource.java     |  88 ---
 .../client/enduser/resources/LoginResource.java    |  92 ---
 .../client/enduser/resources/RealmResource.java    |  76 --
 .../client/enduser/resources/SchemaResource.java   | 203 -----
 .../SecurityQuestionByUsernameResource.java        |  84 ---
 .../resources/SecurityQuestionsResource.java       |  78 --
 .../enduser/resources/UserClassesResource.java     |  75 --
 .../enduser/resources/UserSelfChangePassword.java  |  70 --
 .../resources/UserSelfConfirmPasswordReset.java    |  75 --
 .../enduser/resources/UserSelfCreateResource.java  | 212 ------
 .../client/enduser/resources/UserSelfIsLogged.java |  67 --
 .../enduser/resources/UserSelfPasswordReset.java   |  91 ---
 .../enduser/resources/UserSelfReadResource.java    | 152 ----
 .../enduser/resources/UserSelfUpdateResource.java  | 220 ------
 .../syncope/client/enduser/util/SaltGenerator.java |  48 --
 .../syncope/client/enduser/util/Validation.java    |  96 ---
 .../META-INF/resources/app/css/accessibility.css   |  44 --
 .../app/css/accessibility/accessibilityFont.css    |  81 --
 .../app/css/accessibility/accessibilityHC.css      | 203 -----
 .../resources/META-INF/resources/app/css/app.css   | 110 ---
 .../META-INF/resources/app/css/customSpinner.css   |  49 --
 .../META-INF/resources/app/css/editUser.css        | 822 ---------------------
 .../resources/META-INF/resources/app/css/init.css  |  22 -
 .../resources/META-INF/resources/app/css/login.css |  83 ---
 .../META-INF/resources/app/css/notification.css    |  28 -
 .../META-INF/resources/app/css/passwordReset.css   |  37 -
 .../resources/app/css/templates/dark/editUser.css  |  95 ---
 .../resources/app/css/templates/dark/login.css     |  78 --
 .../META-INF/resources/app/img/ajax-loader.gif     | Bin 1924 -> 0 bytes
 .../resources/META-INF/resources/app/img/busy.gif  | Bin 2834 -> 0 bytes
 .../META-INF/resources/app/img/favicon.png         | Bin 641 -> 0 bytes
 .../META-INF/resources/app/img/logo-green.png      | Bin 12178 -> 0 bytes
 .../resources/META-INF/resources/app/img/logo.png  | Bin 8913 -> 0 bytes
 .../resources/META-INF/resources/app/index.html    | 171 -----
 .../resources/META-INF/resources/app/js/app.js     | 730 ------------------
 .../app/js/controllers/AccessibilityController.js  |  89 ---
 .../resources/app/js/controllers/HomeController.js |  23 -
 .../app/js/controllers/LoginController.js          |  95 ---
 .../app/js/controllers/OIDCClientController.js     |  29 -
 .../app/js/controllers/SAML2SPController.js        |  29 -
 .../resources/app/js/controllers/UserController.js | 678 -----------------
 .../resources/app/js/directives/auxClasses.js      |  59 --
 .../resources/app/js/directives/bpmnProcesses.js   |  39 -
 .../resources/app/js/directives/captcha.js         |  46 --
 .../app/js/directives/dynamicDerivedAttribute.js   |  43 --
 .../app/js/directives/dynamicDerivedAttributes.js  |  73 --
 .../app/js/directives/dynamicPlainAttribute.js     | 147 ----
 .../app/js/directives/dynamicPlainAttributes.js    |  76 --
 .../app/js/directives/dynamicTemplateItem.js       |  79 --
 .../app/js/directives/dynamicVirtualAttribute.js   |  68 --
 .../app/js/directives/dynamicVirtualAttributes.js  |  70 --
 .../resources/app/js/directives/fileInput.js       |  55 --
 .../resources/app/js/directives/formProperty.js    |  83 ---
 .../META-INF/resources/app/js/directives/groups.js |  73 --
 .../META-INF/resources/app/js/directives/loader.js |  32 -
 .../resources/app/js/directives/modalContent.js    |  31 -
 .../resources/app/js/directives/modalWindow.js     |  43 --
 .../app/js/directives/navigationButtonsPartial.js  |  70 --
 .../resources/app/js/directives/ngEnter.js         |  39 -
 .../app/js/directives/passwordStrengthEstimator.js | 102 ---
 .../resources/app/js/directives/requestForms.js    | 110 ---
 .../resources/app/js/directives/requests.js        | 192 -----
 .../resources/app/js/directives/resources.js       |  51 --
 .../resources/app/js/directives/validate.js        |  38 -
 .../app/js/directives/validateDropdown.js          |  77 --
 .../app/js/directives/validationMessage.js         |  78 --
 .../resources/app/js/filters/propsFilter.js        |  52 --
 .../resources/app/js/services/anyService.js        |  53 --
 .../resources/app/js/services/authService.js       |  49 --
 .../app/js/services/bpmnProcessService.js          |  38 -
 .../app/js/services/dynamicTemplateService.js      |  67 --
 .../resources/app/js/services/groupService.js      |  50 --
 .../resources/app/js/services/infoService.js       |  43 --
 .../resources/app/js/services/oidcClientService.js |  42 --
 .../app/js/services/oidcProviderService.js         |  42 --
 .../resources/app/js/services/realmService.js      |  39 -
 .../resources/app/js/services/resourceService.js   |  41 -
 .../resources/app/js/services/saml2IdPService.js   |  42 --
 .../resources/app/js/services/saml2SPService.js    |  42 --
 .../resources/app/js/services/schemaService.js     |  59 --
 .../app/js/services/securityQuestionService.js     |  47 --
 .../app/js/services/userRequestsService.js         |  78 --
 .../resources/app/js/services/userSelfService.js   | 127 ----
 .../resources/app/js/util/assetsManager.js         | 115 ---
 .../META-INF/resources/app/js/util/genericUtil.js  |  57 --
 .../META-INF/resources/app/js/util/userUtil.js     |  71 --
 .../app/js/validator/validationExecutor.js         |  46 --
 .../resources/app/js/validator/validationRules.js  |  67 --
 .../resources/app/languages/de/static.json         |  66 --
 .../resources/app/languages/en/static.json         |  66 --
 .../resources/app/languages/it/static.json         |  65 --
 .../resources/app/languages/ja/static.json         |  66 --
 .../META-INF/resources/app/views/auxClasses.html   |  31 -
 .../resources/app/views/bpmnProcesses.html         |  31 -
 .../META-INF/resources/app/views/captcha.html      |  37 -
 .../resources/app/views/confirmpasswordreset.html  |  21 -
 .../app/views/dynamicDerivedAttribute.html         |  23 -
 .../app/views/dynamicDerivedAttributes.html        |  55 --
 .../resources/app/views/dynamicPlainAttribute.html | 150 ----
 .../app/views/dynamicPlainAttributes.html          |  52 --
 .../app/views/dynamicVirtualAttribute.html         |  23 -
 .../app/views/dynamicVirtualAttributes.html        |  51 --
 .../META-INF/resources/app/views/editUser.html     |  21 -
 .../META-INF/resources/app/views/formProperty.html |  92 ---
 .../META-INF/resources/app/views/groups.html       |  32 -
 .../META-INF/resources/app/views/home.html         |  33 -
 .../META-INF/resources/app/views/modalWindow.html  |  30 -
 .../resources/app/views/mustchangepassword.html    |  21 -
 .../app/views/navigationButtonsPartial.html        |  32 -
 .../resources/app/views/passwordreset.html         |  21 -
 .../META-INF/resources/app/views/requestForms.html |  61 --
 .../META-INF/resources/app/views/requests.html     |  76 --
 .../resources/app/views/requiredMessage.html       |  22 -
 .../META-INF/resources/app/views/resources.html    |  27 -
 .../META-INF/resources/app/views/self.html         |  32 -
 .../templates/confirmPasswordResetTemplate.html    |  83 ---
 .../app/views/templates/editUserTemplate.html      |  58 --
 .../templates/mustChangePasswordTemplate.html      |  82 --
 .../onlyPlainAttrsDetails/editUserTemplate.html    |  57 --
 .../app/views/templates/passwordresetTemplate.html |  82 --
 .../app/views/templates/selfTemplate.html          |  77 --
 .../resources/app/views/user-credentials.html      |  94 ---
 .../resources/app/views/user-derived-schemas.html  |  48 --
 .../resources/app/views/user-form-finish.html      |  46 --
 .../META-INF/resources/app/views/user-groups.html  |  61 --
 .../resources/app/views/user-plain-schemas.html    |  48 --
 .../resources/app/views/user-request-forms.html    |  48 --
 .../resources/app/views/user-requests.html         |  48 --
 .../resources/app/views/user-resources.html        |  48 --
 .../resources/app/views/user-virtual-schemas.html  |  48 --
 .../resources/app/views/validationMessage.html     |  22 -
 .../src/main/resources/customFormAttributes.json   |   1 -
 .../enduser/src/main/resources/customTemplate.json |  82 --
 .../enduser/src/main/resources/enduser.properties  |  28 -
 .../client/enduser/util/ValidationTest.java        |  97 ---
 .../src/test/resources/customFormAttributes.json   |  44 --
 .../enduser/src/test/resources/customTemplate.json |  75 --
 .../syncope/client/ui/commons/BaseSession.java     |   3 +
 ...inFormPanel.java => BaseSSOLoginFormPanel.java} |   4 +-
 .../client/console/SyncopeConsoleApplication.java  |   9 +
 .../client/console/SyncopeConsoleSession.java      |   5 +
 .../init/ClassPathScanImplementationLookup.java    |  13 +-
 .../apache/syncope/client/console/pages/Login.java |   3 +-
 .../client/console/panels/SSOLoginFormPanel.java   |  30 -
 client/idrepo/enduser/pom.xml                      |   6 -
 .../client/enduser/SyncopeEnduserApplication.java  |   9 +
 .../client/enduser/SyncopeEnduserSession.java      |   5 +
 .../client/enduser/SyncopeWebApplication.java      |  34 +-
 .../init/ClassPathScanImplementationLookup.java    |  32 +-
 .../syncope/client/enduser/navigation/Navbar.java  |  33 +
 .../apache/syncope/client/enduser/pages/Login.java |   3 +-
 .../syncope/client/enduser/pages/Logout.java       |  16 +-
 .../apache/syncope/client/enduser/pages/Self.java  |  31 +-
 .../client/enduser/assets/css/syncopeEnduser.scss  |  39 +-
 .../syncope/client/enduser/navigation/Navbar.html  |  43 +-
 client/pom.xml                                     |   1 -
 .../oidcclient/agent/OIDCClientAgentContext.java   |  17 +-
 .../{client-enduser => client-common-ui}/pom.xml   |  35 +-
 .../ui/panels/AbstractOIDCSSOLoginFormPanel.java}  |  16 +-
 .../ui/panels/AbstractOIDCSSOLoginFormPanel.html}  |   2 +
 ext/oidcclient/client-console/pom.xml              |  14 +-
 .../client/console/pages/OIDCClientLogin.java      |   1 -
 .../console/panels/OIDCSSOLoginFormPanel.java      |  89 +--
 .../console/panels/OIDCSSOLoginFormPanel.html      |   8 +-
 ext/oidcclient/client-enduser/pom.xml              |  14 +-
 .../client/enduser/pages/OIDCClientLogin.java      |  11 +-
 .../client/enduser/pages/OIDCClientLogout.java     |   4 +-
 .../client/enduser/pages/OIDCClientSelfReg.java    |   2 +-
 .../enduser/panels/OIDCSSOLoginFormPanel.java      |  19 +-
 .../resources/OIDCClientUserAttrsResource.java     |  65 --
 .../enduser/resources/OIDCProvidersResource.java   |  69 --
 .../enduser/panels/OIDCSSOLoginFormPanel.html      |   8 +-
 .../syncope/core/logic/oidc/OIDCUserManager.java   |   6 +-
 ext/oidcclient/pom.xml                             |   1 +
 .../ext/saml2lsp/agent/SAML2SPAgentContext.java    |  13 +-
 .../{client-enduser => client-common-ui}/pom.xml   |  35 +-
 .../ui/panels/AbstractSAMLSSOLoginFormPanel.java}  |  16 +-
 .../ui/panels/AbstractSAMLSSOLoginFormPanel.html}  |   2 +
 ext/saml2sp/client-console/pom.xml                 |  14 +-
 .../console/panels/SAMLSSOLoginFormPanel.java      |  80 +-
 .../console/panels/SAMLSSOLoginFormPanel.html      |   8 +-
 ext/saml2sp/client-enduser/pom.xml                 |  14 +-
 .../syncope/client/enduser/pages/SAML2SPLogin.java |  11 +-
 .../client/enduser/pages/SAML2SPLogout.java        |   5 +-
 .../client/enduser/pages/SAML2SPSelfReg.java       |   2 +-
 .../enduser/panels/SAMLSSOLoginFormPanel.java      |  17 +-
 .../enduser/resources/SAML2IdPsResource.java       |  72 --
 .../resources/SAML2SPUserAttrsResource.java        |  65 --
 .../enduser/panels/SAMLSSOLoginFormPanel.html      |   7 +-
 .../syncope/core/logic/saml2/SAML2UserManager.java |   2 +-
 ext/saml2sp/pom.xml                                |   1 +
 fit/core-reference/src/test/resources/keystore     | Bin 4329 -> 9263 bytes
 fit/enduser-reference/pom.xml                      |  12 +
 .../src/main/webapp/WEB-INF/web.xml                |   8 +-
 218 files changed, 362 insertions(+), 13764 deletions(-)

diff --git a/client/enduser/pom.xml b/client/enduser/pom.xml
deleted file mode 100644
index 747ab50..0000000
--- a/client/enduser/pom.xml
+++ /dev/null
@@ -1,250 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-  <modelVersion>4.0.0</modelVersion>
-  
-  <parent>
-    <groupId>org.apache.syncope</groupId>
-    <artifactId>syncope-client</artifactId>
-    <version>3.0.0-SNAPSHOT</version>
-  </parent>
-    
-  <name>Apache Syncope Client Enduser</name>
-  <description>Apache Syncope Client Enduser</description>
-  <groupId>org.apache.syncope.client</groupId>
-  <artifactId>syncope-client-enduser</artifactId>
-  <packaging>jar</packaging>
-  
-  <properties>
-    <rootpom.basedir>${basedir}/../..</rootpom.basedir>
-  </properties>
-  
-  <dependencies>
-    <dependency> 
-      <groupId>javax.servlet</groupId> 
-      <artifactId>javax.servlet-api</artifactId>
-      <scope>provided</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>com.giffing.wicket.spring.boot.starter</groupId>
-      <artifactId>wicket-spring-boot-starter</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-log4j2</artifactId>
-    </dependency>
-    
-    <dependency>
-      <groupId>org.apache.wicket</groupId>
-      <artifactId>wicket-extensions</artifactId>
-    </dependency>
- 
-    <dependency>
-      <groupId>org.apache.syncope.client.idm</groupId>
-      <artifactId>syncope-client-idm-lib</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-   
-    <!--AngularJS-->    
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>angular</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>angular-resource</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>angular-ui-router</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>angular-animate</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>angular-cookies</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>angular-treasure-overlay-spinner</artifactId>      
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>angular-translate</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>angular-translate-loader-partial</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>angular-translate-storage-cookie</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>bootstrap-fileinput</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>ng-password-strength</artifactId>    
-    </dependency>
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>lodash</artifactId>        
-    </dependency>
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>kendo-ui-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>angular-aria</artifactId>
-    </dependency>  
-
-    <!--Bootstrap-->
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>font-awesome</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>bootstrap-select</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>bootstrap</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>ionicons</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.npm</groupId>
-      <artifactId>ui-bootstrap4</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>angular-ui-select</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>angular-sanitize</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>select2</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>org.webjars.bower</groupId>
-          <artifactId>jquery</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars.bower</groupId>
-      <artifactId>FileSaver.js</artifactId>
-    </dependency>
-
-    <!--jQuery-->
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>jquery</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>jquery-cookie</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>jquery-ui</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-text</artifactId>
-    </dependency>
-            
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.lmax</groupId>
-      <artifactId>disruptor</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-slf4j-impl</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-logging</groupId>
-      <artifactId>commons-logging</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>jcl-over-slf4j</artifactId>
-    </dependency>
-    
-    <!-- TEST -->
-    <dependency>
-      <groupId>org.junit.jupiter</groupId>
-      <artifactId>junit-jupiter</artifactId>
-      <scope>test</scope>
-    </dependency>
-    
-  </dependencies>
-  
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-      </plugin>
-    </plugins>
-    
-    <resources>
-      <resource>
-        <directory>src/main/resources</directory>
-        <filtering>true</filtering>
-      </resource>
-
-      <resource>
-        <directory>${basedir}/../../src/main/resources</directory>
-        <filtering>true</filtering>
-        <includes>
-          <include>banner.txt</include>
-        </includes>
-      </resource>
-    </resources>    
-  </build>
-</project>
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
deleted file mode 100644
index 0c8d8f9..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser;
-
-import com.giffing.wicket.spring.boot.starter.web.config.WicketWebInitializerAutoConfig.WebSocketWicketWebInitializerAutoConfiguration;
-import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
-import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
-import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
-import org.springframework.context.annotation.Bean;
-import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-@SpringBootApplication
-@EnableAutoConfiguration(exclude = {
-    ErrorMvcAutoConfiguration.class,
-    HttpMessageConvertersAutoConfiguration.class })
-public class SyncopeEnduserApplication extends SpringBootServletInitializer implements WebMvcConfigurer {
-
-    public static void main(final String[] args) {
-        SpringApplication.run(SyncopeEnduserApplication.class, args);
-    }
-
-    @Override
-    protected SpringApplicationBuilder configure(final SpringApplicationBuilder builder) {
-        builder.properties(WebSocketWicketWebInitializerAutoConfiguration.REGISTER_SERVER_ENDPOINT_ENABLED + "=false");
-        return super.configure(builder);
-    }
-
-    @Override
-    public void addViewControllers(final ViewControllerRegistry registry) {
-        registry.addViewController("/app/").setViewName("forward:/app/index.html");
-    }
-
-    @Bean
-    public ClassPathScanImplementationLookup classPathScanImplementationLookup() {
-        ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup();
-        lookup.load();
-        return lookup;
-    }
-}
-
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
deleted file mode 100644
index 5e36f57..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser;
-
-import java.util.List;
-import java.util.stream.Collectors;
-import javax.ws.rs.ForbiddenException;
-import javax.ws.rs.core.EntityTag;
-import javax.ws.rs.core.MediaType;
-import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.syncope.client.lib.AnonymousAuthenticationHandler;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.info.PlatformInfo;
-import org.apache.syncope.common.lib.to.PlainSchemaTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.lib.types.IdRepoEntitlement;
-import org.apache.syncope.common.rest.api.beans.SchemaQuery;
-import org.apache.syncope.common.rest.api.service.SchemaService;
-import org.apache.syncope.common.rest.api.service.SyncopeService;
-import org.apache.wicket.Session;
-import org.apache.wicket.protocol.http.WebSession;
-import org.apache.wicket.request.Request;
-import org.apache.wicket.util.cookies.CookieUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Custom Syncope Enduser Session class.
- */
-public class SyncopeEnduserSession extends WebSession {
-
-    private static final long serialVersionUID = 1284946129513378647L;
-
-    private static final Logger LOG = LoggerFactory.getLogger(SyncopeEnduserSession.class);
-
-    private final SyncopeClient anonymousClient;
-
-    private SyncopeClient client;
-
-    private final PlatformInfo platformInfo;
-
-    private final List<PlainSchemaTO> datePlainSchemas;
-
-    private UserTO selfTO;
-
-    private final CookieUtils cookieUtils;
-
-    private boolean xsrfTokenGenerated = false;
-
-    public static SyncopeEnduserSession get() {
-        return (SyncopeEnduserSession) Session.get();
-    }
-
-    public SyncopeEnduserSession(final Request request) {
-        super(request);
-        // define cookie utility to manage application cookies
-        cookieUtils = new CookieUtils();
-
-        anonymousClient = SyncopeWebApplication.get().getClientFactory().
-                create(new AnonymousAuthenticationHandler(
-                        SyncopeWebApplication.get().getAnonymousUser(),
-                        SyncopeWebApplication.get().getAnonymousKey()));
-        platformInfo = anonymousClient.getService(SyncopeService.class).platform();
-
-        datePlainSchemas = anonymousClient.getService(SchemaService.class).
-                search(new SchemaQuery.Builder().type(SchemaType.PLAIN).build());
-        datePlainSchemas.removeAll(datePlainSchemas.stream().
-                filter(object -> object.getType() != AttrSchemaType.Date).collect(Collectors.toSet()));
-    }
-
-    private void afterAuthentication(final String username) {
-        try {
-            selfTO = client.self().getRight();
-        } catch (ForbiddenException e) {
-            LOG.warn("Could not read self(), probably in a {} scenario", IdRepoEntitlement.MUST_CHANGE_PASSWORD, e);
-
-            selfTO = new UserTO();
-            selfTO.setUsername(username);
-            selfTO.setMustChangePassword(true);
-        }
-
-        // bind explicitly this session to have a stateful behavior during http requests, unless session will
-        // expire for every request
-        this.bind();
-    }
-
-    public boolean authenticate(final String username, final String password) {
-        boolean authenticated = false;
-
-        try {
-            client = SyncopeWebApplication.get().getClientFactory().
-                    setDomain(SyncopeWebApplication.get().getDomain()).
-                    create(username, password);
-
-            afterAuthentication(username);
-
-            authenticated = true;
-        } catch (Exception e) {
-            LOG.error("Authentication failed", e);
-        }
-
-        return authenticated;
-    }
-
-    public boolean authenticate(final String jwt) {
-        boolean authenticated = false;
-
-        try {
-            client = SyncopeWebApplication.get().getClientFactory().
-                    setDomain(SyncopeWebApplication.get().getDomain()).create(jwt);
-
-            afterAuthentication(null);
-
-            authenticated = true;
-        } catch (Exception e) {
-            LOG.error("Authentication failed", e);
-        }
-
-        return authenticated;
-    }
-
-    @Override
-    public void invalidate() {
-        if (isAuthenticated()) {
-            try {
-                client.logout();
-            } catch (Exception e) {
-                LOG.debug("Unexpected exception while logging out", e);
-            } finally {
-                client = null;
-                selfTO = null;
-            }
-        }
-        super.invalidate();
-    }
-
-    public <T> T getService(final Class<T> serviceClass) {
-        return (client == null || !isAuthenticated())
-                ? anonymousClient.getService(serviceClass)
-                : client.getService(serviceClass);
-    }
-
-    public <T> T getService(final String etag, final Class<T> serviceClass) {
-        T serviceInstance = getService(serviceClass);
-        WebClient.client(serviceInstance).match(new EntityTag(etag), false).
-                type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON);
-
-        return serviceInstance;
-    }
-
-    public PlatformInfo getPlatformInfo() {
-        return platformInfo;
-    }
-
-    public List<PlainSchemaTO> getDatePlainSchemas() {
-        return datePlainSchemas;
-    }
-
-    public UserTO getSelfTO() {
-        if (selfTO == null) {
-            throw new IllegalArgumentException("User not authenticated");
-        }
-        return selfTO;
-    }
-
-    public boolean isAuthenticated() {
-        return client != null && client.getJWT() != null;
-    }
-
-    public CookieUtils getCookieUtils() {
-        return cookieUtils;
-    }
-
-    public boolean isXsrfTokenGenerated() {
-        return xsrfTokenGenerated;
-    }
-
-    public void setXsrfTokenGenerated(final boolean xsrfTokenGenerated) {
-        this.xsrfTokenGenerated = xsrfTokenGenerated;
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
deleted file mode 100644
index 2870726..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser;
-
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.giffing.wicket.spring.boot.starter.app.WicketBootSecuredWebApplication;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-import org.apache.syncope.client.enduser.pages.HomePage;
-import java.util.Properties;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.monitor.FileAlterationListener;
-import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
-import org.apache.commons.io.monitor.FileAlterationMonitor;
-import org.apache.commons.io.monitor.FileAlterationObserver;
-import org.apache.commons.lang3.BooleanUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.enduser.model.CustomAttributesInfo;
-import org.apache.syncope.client.enduser.model.CustomTemplateInfo;
-import org.apache.syncope.client.enduser.resources.CaptchaResource;
-import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
-import org.apache.syncope.common.lib.PropertyUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.wicket.Page;
-import org.apache.wicket.Session;
-import org.apache.wicket.WicketRuntimeException;
-import org.apache.wicket.protocol.http.WebApplication;
-import org.apache.wicket.request.Request;
-import org.apache.wicket.request.Response;
-import org.apache.wicket.request.cycle.IRequestCycleListener;
-import org.apache.wicket.request.cycle.RequestCycle;
-import org.apache.wicket.request.http.WebResponse;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.request.resource.IResource;
-import org.apache.wicket.request.resource.ResourceReference;
-import org.apache.wicket.util.lang.Args;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
-
-    private static final Logger LOG = LoggerFactory.getLogger(SyncopeWebApplication.class);
-
-    private static final String ENDUSER_PROPERTIES = "enduser.properties";
-
-    private static final String CUSTOM_FORM_ATTRIBUTES_FILE = "customFormAttributes.json";
-
-    private static final String CUSTOM_TEMPLATE_FILE = "customTemplate.json";
-
-    public static SyncopeWebApplication get() {
-        return (SyncopeWebApplication) WebApplication.get();
-    }
-
-    @Autowired
-    private ClassPathScanImplementationLookup lookup;
-
-    private String domain;
-
-    private String adminUser;
-
-    private String anonymousUser;
-
-    private String anonymousKey;
-
-    private boolean captchaEnabled;
-
-    private boolean xsrfEnabled;
-
-    private Integer maxUploadFileSizeMB;
-
-    private SyncopeClientFactoryBean clientFactory;
-
-    private Map<String, CustomAttributesInfo> customFormAttributes;
-
-    private CustomTemplateInfo customTemplate;
-
-    private static final ObjectMapper MAPPER = new ObjectMapper();
-
-    @Override
-    protected void init() {
-        super.init();
-
-        // read enduser.properties
-        Properties props = PropertyUtils.read(getClass(), ENDUSER_PROPERTIES, "enduser.directory");
-
-        domain = props.getProperty("domain", SyncopeConstants.MASTER_DOMAIN);
-        adminUser = props.getProperty("adminUser");
-        Args.notNull(adminUser, "<adminUser>");
-        anonymousUser = props.getProperty("anonymousUser");
-        Args.notNull(anonymousUser, "<anonymousUser>");
-        anonymousKey = props.getProperty("anonymousKey");
-        Args.notNull(anonymousKey, "<anonymousKey>");
-
-        captchaEnabled = Boolean.parseBoolean(props.getProperty("captcha"));
-        Args.notNull(captchaEnabled, "<captcha>");
-
-        xsrfEnabled = Boolean.parseBoolean(props.getProperty("xsrf"));
-        Args.notNull(xsrfEnabled, "<xsrf>");
-
-        String scheme = props.getProperty("scheme");
-        Args.notNull(scheme, "<scheme>");
-        String host = props.getProperty("host");
-        Args.notNull(host, "<host>");
-        String port = props.getProperty("port");
-        Args.notNull(port, "<port>");
-        String rootPath = props.getProperty("rootPath");
-        Args.notNull(rootPath, "<rootPath>");
-        String useGZIPCompression = props.getProperty("useGZIPCompression");
-        Args.notNull(useGZIPCompression, "<useGZIPCompression>");
-        maxUploadFileSizeMB = props.getProperty("maxUploadFileSizeMB") == null
-                ? null
-                : Integer.valueOf(props.getProperty("maxUploadFileSizeMB"));
-
-        clientFactory = new SyncopeClientFactoryBean().
-                setAddress(scheme + "://" + host + ":" + port + StringUtils.prependIfMissing(rootPath, "/")).
-                setContentType(SyncopeClientFactoryBean.ContentType.JSON).
-                setUseCompression(BooleanUtils.toBoolean(useGZIPCompression));
-
-        // read customFormAttributes.json
-        File enduserDir;
-        try (InputStream is = getClass().getResourceAsStream("/" + CUSTOM_FORM_ATTRIBUTES_FILE)) {
-            customFormAttributes = MAPPER.readValue(is,
-                    new TypeReference<HashMap<String, CustomAttributesInfo>>() {
-            });
-            enduserDir = new File(props.getProperty("enduser.directory"));
-            boolean existsEnduserDir = enduserDir.exists() && enduserDir.canRead() && enduserDir.isDirectory();
-            if (existsEnduserDir) {
-                File customFormAttributesFile = FileUtils.getFile(enduserDir, CUSTOM_FORM_ATTRIBUTES_FILE);
-                if (customFormAttributesFile.exists()
-                        && customFormAttributesFile.canRead()
-                        && customFormAttributesFile.isFile()) {
-                    customFormAttributes = MAPPER.readValue(FileUtils.openInputStream(customFormAttributesFile),
-                            new TypeReference<HashMap<String, CustomAttributesInfo>>() {
-                    });
-                }
-            }
-            FileAlterationObserver observer = existsEnduserDir
-                    ? new FileAlterationObserver(enduserDir,
-                            pathname -> StringUtils.contains(pathname.getPath(), CUSTOM_FORM_ATTRIBUTES_FILE))
-                    : new FileAlterationObserver(getClass().getResource("/" + CUSTOM_FORM_ATTRIBUTES_FILE).getFile(),
-                            pathname -> StringUtils.contains(pathname.getPath(), CUSTOM_FORM_ATTRIBUTES_FILE));
-
-            FileAlterationMonitor monitor = new FileAlterationMonitor(5000);
-
-            FileAlterationListener listener = new FileAlterationListenerAdaptor() {
-
-                @Override
-                public void onFileChange(final File file) {
-                    try {
-                        LOG.trace("{} has changed. Reloading form attributes customization configuration.",
-                                CUSTOM_FORM_ATTRIBUTES_FILE);
-                        customFormAttributes = MAPPER.readValue(FileUtils.openInputStream(file),
-                                new TypeReference<HashMap<String, CustomAttributesInfo>>() {
-                        });
-                    } catch (IOException e) {
-                        e.printStackTrace(System.err);
-                    }
-                }
-
-                @Override
-                public void onFileCreate(final File file) {
-                    try {
-                        LOG.trace("{} has been created. Loading form attributes customization configuration.",
-                                CUSTOM_FORM_ATTRIBUTES_FILE);
-                        customFormAttributes = MAPPER.readValue(FileUtils.openInputStream(file),
-                                new TypeReference<HashMap<String, CustomAttributesInfo>>() {
-                        });
-                    } catch (IOException e) {
-                        e.printStackTrace(System.err);
-                    }
-                }
-
-                @Override
-                public void onFileDelete(final File file) {
-                    LOG.trace("{} has been deleted. Resetting form attributes customization configuration.",
-                            CUSTOM_FORM_ATTRIBUTES_FILE);
-                    customFormAttributes = null;
-                }
-            };
-
-            observer.addListener(listener);
-            monitor.addObserver(observer);
-            monitor.start();
-        } catch (Exception e) {
-            throw new WicketRuntimeException("Could not read " + CUSTOM_FORM_ATTRIBUTES_FILE, e);
-        }
-
-        // read customTemplate.json
-        try (InputStream is = getClass().getResourceAsStream("/" + CUSTOM_TEMPLATE_FILE)) {
-            customTemplate = MAPPER.readValue(is, CustomTemplateInfo.class);
-            enduserDir = new File(props.getProperty("enduser.directory"));
-            boolean existsEnduserDir = enduserDir.exists() && enduserDir.canRead() && enduserDir.isDirectory();
-            if (existsEnduserDir) {
-                File customTemplateFile = FileUtils.getFile(enduserDir, CUSTOM_TEMPLATE_FILE);
-                if (customTemplateFile.exists()
-                        && customTemplateFile.canRead()
-                        && customTemplateFile.isFile()) {
-                    customTemplate = MAPPER.readValue(FileUtils.openInputStream(customTemplateFile),
-                            CustomTemplateInfo.class);
-                }
-            }
-            FileAlterationObserver observer = existsEnduserDir
-                    ? new FileAlterationObserver(enduserDir,
-                            pathname -> StringUtils.contains(pathname.getPath(), CUSTOM_TEMPLATE_FILE))
-                    : new FileAlterationObserver(getClass().getResource("/" + CUSTOM_TEMPLATE_FILE).getFile(),
-                            pathname -> StringUtils.contains(pathname.getPath(), CUSTOM_TEMPLATE_FILE));
-
-            FileAlterationMonitor monitor = new FileAlterationMonitor(5000);
-
-            FileAlterationListener listener = new FileAlterationListenerAdaptor() {
-
-                @Override
-                public void onFileChange(final File file) {
-                    try {
-                        LOG.trace("{} has changed. Reloading app customization configuration.",
-                                CUSTOM_TEMPLATE_FILE);
-                        customTemplate = MAPPER.readValue(FileUtils.openInputStream(file),
-                                CustomTemplateInfo.class);
-                    } catch (IOException e) {
-                        e.printStackTrace(System.err);
-                    }
-                }
-
-                @Override
-                public void onFileCreate(final File file) {
-                    try {
-                        LOG.trace("{} has been created. Loading app customization configuration.",
-                                CUSTOM_TEMPLATE_FILE);
-                        customTemplate = MAPPER.readValue(FileUtils.openInputStream(file),
-                                CustomTemplateInfo.class);
-                    } catch (IOException e) {
-                        e.printStackTrace(System.err);
-                    }
-                }
-
-                @Override
-                public void onFileDelete(final File file) {
-                    LOG.trace("{} has been deleted. Resetting app customization configuration.",
-                            CUSTOM_TEMPLATE_FILE);
-                    customTemplate = null;
-                }
-            };
-
-            observer.addListener(listener);
-            monitor.addObserver(observer);
-            monitor.start();
-        } catch (Exception e) {
-            throw new WicketRuntimeException("Could not read " + CUSTOM_TEMPLATE_FILE, e);
-        }
-
-        // mount resources
-        for (Class<? extends AbstractResource> resource : lookup.getResources()) {
-            Resource annotation = resource.getAnnotation(Resource.class);
-            if (annotation == null) {
-                LOG.debug("No @Resource annotation found on {}, ignoring", resource.getName());
-            } else {
-                try {
-                    AbstractResource instance = resource.getDeclaredConstructor().newInstance();
-
-                    mountResource(annotation.path(), new ResourceReference(annotation.key()) {
-
-                        private static final long serialVersionUID = -128426276529456602L;
-
-                        @Override
-                        public IResource getResource() {
-                            return instance;
-                        }
-                    });
-                } catch (Exception e) {
-                    LOG.error("Could not instantiate {}", resource.getName(), e);
-                }
-            }
-        }
-        //mount captcha resource only if captcha is enabled
-        if (captchaEnabled) {
-            mountResource("/api/captcha", new ResourceReference("captcha") {
-
-                private static final long serialVersionUID = -128426276529456602L;
-
-                @Override
-                public IResource getResource() {
-                    return new CaptchaResource();
-                }
-            });
-        }
-
-        getRequestCycleListeners().add(new IRequestCycleListener() {
-
-            @Override
-            public void onEndRequest(final RequestCycle cycle) {
-                if (cycle.getResponse() instanceof WebResponse) {
-                    WebResponse response = (WebResponse) cycle.getResponse();
-                    response.setHeader("X-XSS-Protection", "1; mode=block");
-                    response.setHeader("X-Content-Type-Options", "nosniff");
-                    response.setHeader("X-Frame-Options", "sameorigin");
-                }
-            }
-        });
-    }
-
-    @Override
-    public Class<? extends Page> getHomePage() {
-        return HomePage.class;
-    }
-
-    @Override
-    public Session newSession(final Request request, final Response response) {
-        return new SyncopeEnduserSession(request);
-    }
-
-    public String getDomain() {
-        return domain;
-    }
-
-    public String getAdminUser() {
-        return adminUser;
-    }
-
-    public String getAnonymousUser() {
-        return anonymousUser;
-    }
-
-    public String getAnonymousKey() {
-        return anonymousKey;
-    }
-
-    public SyncopeClientFactoryBean getClientFactory() {
-        return clientFactory;
-    }
-
-    public boolean isCaptchaEnabled() {
-        return captchaEnabled;
-    }
-
-    public boolean isXsrfEnabled() {
-        return xsrfEnabled;
-    }
-
-    public Integer getMaxUploadFileSizeMB() {
-        return maxUploadFileSizeMB;
-    }
-
-    public Map<String, CustomAttributesInfo> getCustomFormAttributes() {
-        return customFormAttributes;
-    }
-
-    public void setCustomFormAttributes(final Map<String, CustomAttributesInfo> customFormAttributes) {
-        this.customFormAttributes.clear();
-        this.customFormAttributes.putAll(customFormAttributes);
-    }
-
-    public void setCustomTemplate(final CustomTemplateInfo customTemplate) {
-        this.customTemplate = customTemplate;
-    }
-
-    public CustomTemplateInfo getCustomTemplate() {
-        return customTemplate;
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/adapters/PlatformInfoAdapter.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/adapters/PlatformInfoAdapter.java
deleted file mode 100644
index 4f60fc9..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/adapters/PlatformInfoAdapter.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.adapters;
-
-import java.util.Map;
-import org.apache.syncope.client.enduser.SyncopeWebApplication;
-import org.apache.syncope.client.enduser.model.CustomAttributesInfo;
-import org.apache.syncope.client.enduser.model.PlatformInfoRequest;
-import org.apache.syncope.common.lib.info.PlatformInfo;
-
-public final class PlatformInfoAdapter {
-
-    public static PlatformInfoRequest toPlatformInfoRequest(final PlatformInfo platformInfo,
-            final Map<String, CustomAttributesInfo> customFormAttributes) {
-        PlatformInfoRequest request = new PlatformInfoRequest();
-        request.setPwdResetAllowed(platformInfo.isPwdResetAllowed());
-        request.setSelfRegAllowed(platformInfo.isSelfRegAllowed());
-        request.setPwdResetRequiringSecurityQuestions(platformInfo.isPwdResetRequiringSecurityQuestions());
-        request.setVersion(platformInfo.getVersion());
-        request.setCaptchaEnabled(SyncopeWebApplication.get().isCaptchaEnabled());
-        if (SyncopeWebApplication.get().getMaxUploadFileSizeMB() != null) {
-            request.setMaxUploadFileSizeMB(SyncopeWebApplication.get().getMaxUploadFileSizeMB());
-        }
-        request.setCustomFormAttributes(customFormAttributes);
-
-        return request;
-    }
-
-    private PlatformInfoAdapter() {
-        // private constructor for static utility class
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/annotations/Resource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/annotations/Resource.java
deleted file mode 100644
index b54e142..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/annotations/Resource.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.annotations;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target({ ElementType.TYPE })
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface Resource {
-
-    /**
-     * @return string for {@link org.apache.wicket.request.resource.ResourceReference#ResourceReference}
-     */
-    String key();
-
-    /**
-     * @return path for{@link org.apache.wicket.protocol.http.WebApplication#mountResource}
-     */
-    String path();
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/commons/Constants.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/commons/Constants.java
deleted file mode 100644
index 4a8189c..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/commons/Constants.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.commons;
-
-public final class Constants {
-
-    public static final String BEFORE_LOGOUT = "beforeLogoutPage";
-
-    private Constants() {
-        // private constructor for static utility class
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/init/ClassPathScanImplementationLookup.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/init/ClassPathScanImplementationLookup.java
deleted file mode 100644
index a482122..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/init/ClassPathScanImplementationLookup.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.init;
-
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
-import org.springframework.core.type.filter.AssignableTypeFilter;
-import org.springframework.util.ClassUtils;
-
-public class ClassPathScanImplementationLookup {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ClassPathScanImplementationLookup.class);
-
-    private static final String DEFAULT_BASE_PACKAGE = "org.apache.syncope.client.enduser";
-
-    private List<Class<? extends AbstractResource>> resources;
-
-    /**
-     * This method can be overridden by subclasses to customize classpath scan.
-     *
-     * @return basePackage for classpath scanning
-     */
-    protected String getBasePackage() {
-        return DEFAULT_BASE_PACKAGE;
-    }
-
-    @SuppressWarnings("unchecked")
-    public void load() {
-        resources = new ArrayList<>();
-
-        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
-        scanner.addIncludeFilter(new AssignableTypeFilter(AbstractResource.class));
-
-        for (BeanDefinition bd : scanner.findCandidateComponents(getBasePackage())) {
-            try {
-                Class<?> clazz = ClassUtils.resolveClassName(bd.getBeanClassName(), ClassUtils.getDefaultClassLoader());
-                boolean isAbsractClazz = Modifier.isAbstract(clazz.getModifiers());
-
-                if (!isAbsractClazz) {
-                    if (AbstractResource.class.isAssignableFrom(clazz)) {
-                        if (clazz.isAnnotationPresent(Resource.class)) {
-                            resources.add((Class<? extends AbstractResource>) clazz);
-                        } else {
-                            LOG.error("Could not find annotation {} in {}, ignoring",
-                                    Resource.class.getName(), clazz.getName());
-                        }
-                    }
-                }
-            } catch (Throwable t) {
-                LOG.warn("Could not inspect class {}", bd.getBeanClassName(), t);
-            }
-        }
-        resources = Collections.unmodifiableList(resources);
-    }
-
-    public List<Class<? extends AbstractResource>> getResources() {
-        return resources;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/Credentials.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/Credentials.java
deleted file mode 100644
index 68e3106..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/Credentials.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Credentials {
-
-    private String username;
-
-    private String password;
-
-    public Credentials() {
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(final String username) {
-        this.username = username;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(final String password) {
-        this.password = password;
-    }
-
-    public Credentials username(final String username) {
-        this.username = username;
-        return this;
-    }
-
-    public Credentials password(final String password) {
-        this.password = password;
-        return this;
-    }
-
-    @Override
-    public String toString() {
-        return ToStringBuilder.reflectionToString(this);
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomAttribute.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomAttribute.java
deleted file mode 100644
index 7d713f0..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomAttribute.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.model;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-public class CustomAttribute implements Serializable {
-
-    private static final long serialVersionUID = 4910266842123376686L;
-
-    private boolean readonly;
-
-    private List<String> defaultValues = new ArrayList<>();
-
-    public CustomAttribute() {
-    }
-
-    public boolean isReadonly() {
-        return readonly;
-    }
-
-    public void setReadonly(final boolean readonly) {
-        this.readonly = readonly;
-    }
-
-    public List<String> getDefaultValues() {
-        return defaultValues;
-    }
-
-    public void setDefaultValues(final List<String> defaultValues) {
-        this.defaultValues = defaultValues;
-    }
-
-    public CustomAttribute readonly(final Boolean value) {
-        this.readonly = value;
-        return this;
-    }
-
-    public CustomAttribute defaultValues(final List<String> value) {
-        this.defaultValues = value;
-        return this;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomAttributesInfo.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomAttributesInfo.java
deleted file mode 100644
index c49253c..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomAttributesInfo.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.model;
-
-import java.io.Serializable;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-public class CustomAttributesInfo implements Serializable {
-
-    private static final long serialVersionUID = 878444785696091916L;
-
-    private Map<String, CustomAttribute> attributes = new LinkedHashMap<>();
-
-    public CustomAttributesInfo() {
-    }
-
-    public Map<String, CustomAttribute> getAttributes() {
-        return attributes;
-    }
-
-    public void setAttributes(final Map<String, CustomAttribute> attributes) {
-        this.attributes = attributes;
-    }
-
-    public CustomAttributesInfo attributes(final Map<String, CustomAttribute> value) {
-        this.attributes = value;
-        return this;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomTemplate.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomTemplate.java
deleted file mode 100644
index 19d4a5b..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomTemplate.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.model;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-public class CustomTemplate implements Serializable {
-
-    private static final long serialVersionUID = -3870675034923683299L;
-
-    private String templateUrl;
-
-    private List<String> css = new ArrayList<>();
-
-    private List<String> js = new ArrayList<>();
-
-    public CustomTemplate() {
-    }
-
-    public String getTemplateUrl() {
-        return templateUrl;
-    }
-
-    public void setTemplateUrl(final String templateUrl) {
-        this.templateUrl = templateUrl;
-    }
-
-    public List<String> getCss() {
-        return css;
-    }
-
-    public void setCss(final List<String> css) {
-        this.css = css;
-    }
-
-    public List<String> getJs() {
-        return js;
-    }
-
-    public void setJs(final List<String> js) {
-        this.js = js;
-    }
-
-    public CustomTemplate templateUrl(final String value) {
-        this.templateUrl = value;
-        return this;
-    }
-
-    public CustomTemplate css(final List<String> value) {
-        this.css = value;
-        return this;
-    }
-
-    public CustomTemplate js(final List<String> value) {
-        this.js = value;
-        return this;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomTemplateInfo.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomTemplateInfo.java
deleted file mode 100644
index d2fe9c1..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomTemplateInfo.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.model;
-
-import java.io.Serializable;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-public class CustomTemplateInfo implements Serializable {
-
-    private static final long serialVersionUID = -3422125754029851539L;
-
-    private Map<String, CustomTemplate> templates = new LinkedHashMap<>();
-
-    private CustomTemplateWizard wizard = new CustomTemplateWizard();
-
-    private Map<String, List<String>> generalAssets = new LinkedHashMap<>();
-
-    public CustomTemplateInfo() {
-    }
-
-    public Map<String, CustomTemplate> getTemplates() {
-        return templates;
-    }
-
-    public void setTemplates(final Map<String, CustomTemplate> templates) {
-        this.templates = templates;
-    }
-
-    public CustomTemplateWizard getWizard() {
-        return wizard;
-    }
-
-    public void setWizard(final CustomTemplateWizard wizard) {
-        this.wizard = wizard;
-    }
-
-    public Map<String, List<String>> getGeneralAssets() {
-        return generalAssets;
-    }
-
-    public void setGeneralAssets(final Map<String, List<String>> generalAssets) {
-        this.generalAssets = generalAssets;
-    }
-
-    public CustomTemplateInfo templates(final Map<String, CustomTemplate> templates,
-            final CustomTemplateWizard wizard, final Map<String, List<String>> generalAssets) {
-
-        this.templates = templates;
-        this.wizard = wizard;
-        this.generalAssets = generalAssets;
-        return this;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomTemplateWizard.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomTemplateWizard.java
deleted file mode 100644
index 3952f9b..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/CustomTemplateWizard.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.model;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-public class CustomTemplateWizard implements Serializable {
-
-    private static final long serialVersionUID = -4290154059045309105L;
-
-    private String firstStep;
-
-    private Map<String, CustomTemplateUrl> steps = new HashMap<>();
-
-    public String getFirstStep() {
-        return firstStep;
-    }
-
-    public void setFirstStep(final String firstStep) {
-        this.firstStep = firstStep;
-    }
-
-    public Map<String, CustomTemplateUrl> getSteps() {
-        return steps;
-    }
-
-    public void setSteps(final Map<String, CustomTemplateUrl> steps) {
-        this.steps = steps;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/PlatformInfoRequest.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/PlatformInfoRequest.java
deleted file mode 100644
index bd80359..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/PlatformInfoRequest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.model;
-
-import java.io.Serializable;
-import java.util.Map;
-
-public class PlatformInfoRequest implements Serializable {
-
-    private static final long serialVersionUID = -6763020920564016374L;
-
-    private String version;
-
-    private boolean selfRegAllowed;
-
-    private boolean pwdResetAllowed;
-
-    private boolean pwdResetRequiringSecurityQuestions;
-
-    private boolean captchaEnabled;
-
-    private int maxUploadFileSizeMB;
-
-    private Map<String, CustomAttributesInfo> customFormAttributes;
-
-    public PlatformInfoRequest() {
-    }
-
-    public String getVersion() {
-        return version;
-    }
-
-    public boolean isSelfRegAllowed() {
-        return selfRegAllowed;
-    }
-
-    public boolean isPwdResetAllowed() {
-        return pwdResetAllowed;
-    }
-
-    public boolean isCaptchaEnabled() {
-        return captchaEnabled;
-    }
-
-    public boolean isPwdResetRequiringSecurityQuestions() {
-        return pwdResetRequiringSecurityQuestions;
-    }
-
-    public void setVersion(final String version) {
-        this.version = version;
-    }
-
-     public int getMaxUploadFileSizeMB() {
-        return maxUploadFileSizeMB;
-    }
-    
-    public void setSelfRegAllowed(final boolean selfRegAllowed) {
-        this.selfRegAllowed = selfRegAllowed;
-    }
-
-    public void setPwdResetAllowed(final boolean pwdResetAllowed) {
-        this.pwdResetAllowed = pwdResetAllowed;
-    }
-
-    public void setPwdResetRequiringSecurityQuestions(final boolean pwdResetRequiringSecurityQuestions) {
-        this.pwdResetRequiringSecurityQuestions = pwdResetRequiringSecurityQuestions;
-    }
-
-    public void setCaptchaEnabled(final boolean captchaEnabled) {
-        this.captchaEnabled = captchaEnabled;
-    }
-
-    public void setMaxUploadFileSizeMB(final int maxUploadFileSizeMB) {
-        this.maxUploadFileSizeMB = maxUploadFileSizeMB;
-    }
-
-    public Map<String, CustomAttributesInfo> getCustomFormAttributes() {
-        return customFormAttributes;
-    }
-
-    public void setCustomFormAttributes(final Map<String, CustomAttributesInfo> customFormAttributes) {
-        this.customFormAttributes = customFormAttributes;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/SchemaResponse.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/SchemaResponse.java
deleted file mode 100644
index e59374e..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/SchemaResponse.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.model;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.syncope.common.lib.to.SchemaTO;
-
-public class SchemaResponse implements Serializable {
-
-    private static final long serialVersionUID = -8896862106241712829L;
-
-    private List<SchemaTO> plainSchemas = new ArrayList<>();
-
-    private List<SchemaTO> derSchemas = new ArrayList<>();
-
-    private List<SchemaTO> virSchemas = new ArrayList<>();
-
-    public SchemaResponse() {
-    }
-
-    public List<SchemaTO> getPlainSchemas() {
-        return plainSchemas;
-    }
-
-    public void setPlainSchemas(final List<SchemaTO> plainSchemas) {
-        this.plainSchemas = plainSchemas;
-    }
-
-    public List<SchemaTO> getDerSchemas() {
-        return derSchemas;
-    }
-
-    public void setDerSchemas(final List<SchemaTO> derSchemas) {
-        this.derSchemas = derSchemas;
-    }
-
-    public List<SchemaTO> getVirSchemas() {
-        return virSchemas;
-    }
-
-    public void setVirSchemas(final List<SchemaTO> virSchemas) {
-        this.virSchemas = virSchemas;
-    }
-
-    public SchemaResponse plainSchemas(final List<SchemaTO> value) {
-        this.plainSchemas = value;
-        return this;
-    }
-
-    public SchemaResponse derSchemas(final List<SchemaTO> value) {
-        this.derSchemas = value;
-        return this;
-    }
-
-    public SchemaResponse virSchemas(final List<SchemaTO> value) {
-        this.virSchemas = value;
-        return this;
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/pages/HomePage.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/pages/HomePage.java
deleted file mode 100644
index e5e1632..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/pages/HomePage.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.pages;
-
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import org.apache.wicket.NonResettingRestartException;
-import org.apache.wicket.markup.html.WebPage;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
-
-public class HomePage extends WebPage {
-
-    private static final long serialVersionUID = -3422492668689122688L;
-
-    public HomePage(final PageParameters parameters) {
-        super(parameters);
-
-        StringBuilder redirectUrl = new StringBuilder("/app/");
-        if (!parameters.get("errorMessage").isNull()) {
-            redirectUrl.append("#!self?errorMessage=");
-            appendMessage(redirectUrl, parameters.get("errorMessage").toString());
-        } else if (!parameters.get("successMessage").isNull()) {
-            redirectUrl.append("#!self?successMessage=");
-            appendMessage(redirectUrl, parameters.get("successMessage").toString());
-        } else if (!parameters.get("saml2SPUserAttrs").isNull()) {
-            redirectUrl.append("#!self-saml2sp");
-        } else if (!parameters.get("oidcClientUserAttrs").isNull()) {
-            redirectUrl.append("#!self-oidcclient");
-        }
-        throw new NonResettingRestartException(redirectUrl.toString());
-    }
-
-    private void appendMessage(final StringBuilder redirectUrl, final String message) {
-        try {
-            redirectUrl.append(URLEncoder.encode(message, StandardCharsets.UTF_8));
-        } catch (Exception e) {
-            redirectUrl.append("Generic error");
-        }
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AnyTypeClassResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AnyTypeClassResource.java
deleted file mode 100644
index 5a75776..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AnyTypeClassResource.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.common.rest.api.service.SyncopeService;
-import org.apache.wicket.request.resource.AbstractResource;
-
-@Resource(key = "auxClasses", path = "/api/auxClasses")
-public class AnyTypeClassResource extends BaseResource {
-
-    private static final long serialVersionUID = 7475706378304995200L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final Attributes attributes) {
-        LOG.debug("Get all available auxiliary classes");
-
-        ResourceResponse response = new ResourceResponse();
-        response.setContentType(MediaType.APPLICATION_JSON);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            final List<String> anyTypeClasses = SyncopeEnduserSession.get().
-                    getService(SyncopeService.class).platform().getAnyTypeClasses();
-
-            response.setTextEncoding(StandardCharsets.UTF_8.name());
-            response.setWriteCallback(new AbstractResource.WriteCallback() {
-
-                @Override
-                public void writeData(final Attributes attributes) throws IOException {
-                    attributes.getResponse().write(MAPPER.writeValueAsString(anyTypeClasses));
-                }
-            });
-            response.setStatusCode(Response.Status.OK.getStatusCode());
-        } catch (Exception e) {
-            LOG.error("Error retrieving available auxiliary classes", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-        return response;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/BaseResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/BaseResource.java
deleted file mode 100644
index c948778..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/BaseResource.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import javax.servlet.http.HttpServletRequest;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.enduser.SyncopeWebApplication;
-import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class BaseResource extends AbstractResource {
-
-    private static final long serialVersionUID = -7875801358718612782L;
-
-    protected static final Logger LOG = LoggerFactory.getLogger(BaseResource.class);
-
-    protected static final ObjectMapper MAPPER = new ObjectMapper()
-            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-
-    protected final boolean xsrfCheck(final HttpServletRequest request) {
-        final String requestXSRFHeader = request.getHeader(SyncopeEnduserConstants.XSRF_HEADER_NAME);
-        return SyncopeWebApplication.get().isXsrfEnabled()
-                ? StringUtils.isNotBlank(requestXSRFHeader)
-                && SyncopeEnduserSession.get().getCookieUtils().
-                        getCookie(SyncopeEnduserConstants.XSRF_COOKIE).getValue().equals(requestXSRFHeader)
-                : true;
-    }
-
-    protected final boolean captchaCheck(final String enteredCaptcha, final Object currentCaptcha) {
-        return SyncopeWebApplication.get().isCaptchaEnabled()
-                ? StringUtils.isBlank(currentCaptcha.toString()) || enteredCaptcha == null
-                ? false
-                : enteredCaptcha.equals(currentCaptcha.toString())
-                : true;
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/BaseUserSelfResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/BaseUserSelfResource.java
deleted file mode 100644
index 310f6a5..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/BaseUserSelfResource.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.text.ParseException;
-import java.util.ListIterator;
-import java.util.Set;
-import org.apache.commons.lang3.time.FastDateFormat;
-import org.apache.syncope.common.lib.Attr;
-import org.apache.syncope.common.lib.to.PlainSchemaTO;
-
-public abstract class BaseUserSelfResource extends BaseResource {
-
-    private static final long serialVersionUID = -5892402817902884085L;
-
-    protected void dateToMillis(final Set<Attr> attrs, final PlainSchemaTO plainSchema)
-            throws ParseException {
-
-        final FastDateFormat fmt = FastDateFormat.getInstance(plainSchema.getConversionPattern());
-        attrs.stream().
-                filter(attr -> (attr.getSchema().equals(plainSchema.getKey()))).
-                forEachOrdered(attr -> {
-                    for (ListIterator<String> itor = attr.getValues().listIterator(); itor.hasNext();) {
-                        String value = itor.next();
-                        try {
-                            itor.set(String.valueOf(fmt.parse(value).getTime()));
-                        } catch (ParseException ex) {
-                            LOG.error("Unable to parse date {}", value);
-                        }
-                    }
-                });
-    }
-
-    protected void millisToDate(final Set<Attr> attrs, final PlainSchemaTO plainSchema)
-            throws IllegalArgumentException {
-
-        final FastDateFormat fmt = FastDateFormat.getInstance(plainSchema.getConversionPattern());
-        attrs.stream().
-                filter(attr -> (attr.getSchema().equals(plainSchema.getKey()))).
-                forEachOrdered(attr -> {
-                    for (ListIterator<String> itor = attr.getValues().listIterator(); itor.hasNext();) {
-                        String value = itor.next();
-                        try {
-                            itor.set(fmt.format(Long.valueOf(value)));
-                        } catch (NumberFormatException ex) {
-                            LOG.error("Invalid format value for {}", value);
-                        }
-                    }
-                });
-    }
-
-    protected void buildResponse(final ResourceResponse response, final int statusCode, final String message) {
-        response.setTextEncoding(StandardCharsets.UTF_8.name());
-        response.setStatusCode(statusCode);
-        response.setWriteCallback(new WriteCallback() {
-
-            @Override
-            public void writeData(final Attributes attributes) throws IOException {
-                attributes.getResponse().write(message);
-            }
-        });
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/CaptchaResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/CaptchaResource.java
deleted file mode 100644
index 7cbb5f5..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/CaptchaResource.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.security.SecureRandom;
-import javax.servlet.http.HttpServletRequest;
-import org.apache.commons.text.RandomStringGenerator;
-import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
-import org.apache.wicket.extensions.markup.html.captcha.CaptchaImageResource;
-import org.apache.wicket.request.cycle.RequestCycle;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class CaptchaResource extends CaptchaImageResource {
-
-    private static final long serialVersionUID = 8293404296348102926L;
-
-    private static final SecureRandom RANDOM = new SecureRandom();
-
-    private static final Logger LOG = LoggerFactory.getLogger(CaptchaResource.class);
-
-    private static final RandomStringGenerator RANDOM_LETTERS = new RandomStringGenerator.Builder().
-            usingRandom(RANDOM::nextInt).
-            withinRange('a', 'z').
-            build();
-
-    @Override
-    protected byte[] render() {
-        LOG.debug("Generate captcha");
-
-        String captcha = RANDOM_LETTERS.generate(6);
-        HttpServletRequest request = ((HttpServletRequest) RequestCycle.get().getRequest().getContainerRequest());
-        // store the captcha in the current session
-        request.getSession().setAttribute(SyncopeEnduserConstants.CAPTCHA_SESSION_KEY, captcha);
-
-        getChallengeIdModel().setObject(captcha);
-        return super.render();
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/DynamicTemplateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/DynamicTemplateResource.java
deleted file mode 100644
index ec62a08..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/DynamicTemplateResource.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import static org.apache.syncope.client.enduser.resources.BaseResource.MAPPER;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.enduser.SyncopeWebApplication;
-import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.client.enduser.model.CustomTemplateInfo;
-import org.apache.syncope.client.enduser.util.SaltGenerator;
-import org.apache.wicket.request.resource.IResource;
-import org.apache.wicket.util.cookies.CookieUtils;
-
-@Resource(key = "info", path = "/api/dynamicTemplate")
-public class DynamicTemplateResource extends BaseResource {
-
-    private static final long serialVersionUID = 7181372091437530936L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-        ResourceResponse response = new ResourceResponse();
-        response.setContentType(MediaType.APPLICATION_JSON);
-
-        try {
-            final CookieUtils sessionCookieUtils = SyncopeEnduserSession.get().getCookieUtils();
-            // set XSRF_TOKEN cookie
-            if (!SyncopeEnduserSession.get().isXsrfTokenGenerated() && (sessionCookieUtils.getCookie(
-                    SyncopeEnduserConstants.XSRF_COOKIE) == null || StringUtils.isBlank(
-                            sessionCookieUtils.getCookie(SyncopeEnduserConstants.XSRF_COOKIE).getValue()))) {
-                LOG.debug("Set XSRF-TOKEN cookie");
-                SyncopeEnduserSession.get().setXsrfTokenGenerated(true);
-                sessionCookieUtils.save(SyncopeEnduserConstants.XSRF_COOKIE,
-                        SaltGenerator.generate(SyncopeEnduserSession.get().getId()));
-            }
-            response.setTextEncoding(StandardCharsets.UTF_8.name());
-            response.setWriteCallback(new WriteCallback() {
-
-                @Override
-                public void writeData(final IResource.Attributes attributes) throws IOException {
-                    CustomTemplateInfo customTemplate = SyncopeWebApplication.get().getCustomTemplate();
-                    attributes.getResponse().write(MAPPER.writeValueAsString(customTemplate));
-                }
-            });
-            response.setStatusCode(Response.Status.OK.getStatusCode());
-        } catch (Exception e) {
-            LOG.error("Error retrieving syncope custom dynamic template", e);
-            response.setError(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-
-        return response;
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/ExternalResourceResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/ExternalResourceResource.java
deleted file mode 100644
index e495816..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/ExternalResourceResource.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.List;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.client.enduser.SyncopeWebApplication;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.client.enduser.model.CustomTemplateInfo;
-import org.apache.syncope.common.rest.api.service.SyncopeService;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.request.resource.IResource;
-
-@Resource(key = "resources", path = "/api/resources")
-public class ExternalResourceResource extends BaseResource {
-
-    private static final long serialVersionUID = 7475706378304995200L;
-
-    @Override
-    protected AbstractResource.ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-        LOG.debug("Search all available resources");
-
-        ResourceResponse response = new AbstractResource.ResourceResponse();
-        response.setContentType(MediaType.APPLICATION_JSON);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            CustomTemplateInfo customTemplate =
-                    SyncopeWebApplication.get().getCustomTemplate();
-            final List<String> resources = customTemplate.getWizard().getSteps().containsKey("groups")
-                    ? SyncopeEnduserSession.get().
-                            getService(SyncopeService.class).platform().getResources()
-                    : Collections.<String>emptyList();
-
-            response.setWriteCallback(new AbstractResource.WriteCallback() {
-
-                @Override
-                public void writeData(final IResource.Attributes attributes) throws IOException {
-                    attributes.getResponse().write(MAPPER.writeValueAsString(resources));
-                }
-            });
-
-            response.setTextEncoding(StandardCharsets.UTF_8.name());
-            response.setStatusCode(Response.Status.OK.getStatusCode());
-        } catch (Exception e) {
-            LOG.error("Error retrieving available resources", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-        return response;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/GroupResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/GroupResource.java
deleted file mode 100644
index d48bd15..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/GroupResource.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.io.IOException;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.client.enduser.SyncopeWebApplication;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.client.enduser.model.CustomTemplateInfo;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.rest.api.service.SyncopeService;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.util.string.StringValue;
-
-@Resource(key = "groups", path = "/api/groups")
-public class GroupResource extends BaseResource {
-
-    private static final long serialVersionUID = 7475706378304995200L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final Attributes attributes) {
-        LOG.debug("Search all available groups");
-
-        ResourceResponse response = new ResourceResponse();
-        response.setContentType(MediaType.APPLICATION_JSON);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            CustomTemplateInfo customTemplate =
-                    SyncopeWebApplication.get().getCustomTemplate();
-            final GroupResponse groupResponse = new GroupResponse();
-            if (customTemplate.getWizard().getSteps().containsKey("groups")) {
-                String realm = URLDecoder.decode(attributes.getParameters().get("realm").
-                        toString(SyncopeConstants.ROOT_REALM), StandardCharsets.UTF_8);
-                StringValue term = attributes.getParameters().get("term");
-
-                final int totGroups = SyncopeEnduserSession.get().
-                        getService(SyncopeService.class).numbers().getTotalGroups();
-                final List<GroupTO> groupTOs = SyncopeEnduserSession.get().
-                        getService(SyncopeService.class).searchAssignableGroups(
-                        realm,
-                        term.isNull() || term.isEmpty()
-                        ? null : URLDecoder.decode(term.toString(), StandardCharsets.UTF_8),
-                        1,
-                        30).getResult();
-                groupResponse.setTotGroups(totGroups);
-                groupResponse.setGroupTOs(groupTOs.stream().
-                        collect(Collectors.toMap(GroupTO::getKey, GroupTO::getName)));
-            } else {
-                groupResponse.setTotGroups(0);
-                Map<String, String> groups = new HashMap<>();
-                groupResponse.setGroupTOs(groups);
-            }
-
-            response.setWriteCallback(new AbstractResource.WriteCallback() {
-
-                @Override
-                public void writeData(final Attributes attributes) throws IOException {
-                    attributes.getResponse().write(MAPPER.writeValueAsString(groupResponse));
-                }
-            });
-            response.setTextEncoding(StandardCharsets.UTF_8.name());
-            response.setStatusCode(Response.Status.OK.getStatusCode());
-        } catch (Exception e) {
-            LOG.error("Error retrieving available groups", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-        return response;
-    }
-
-    private class GroupResponse {
-
-        private Map<String, String> groups;
-
-        private int totGroups;
-
-        public Map<String, String> getGroupTOs() {
-            return Collections.unmodifiableMap(groups);
-        }
-
-        public void setGroupTOs(final Map<String, String> groups) {
-            this.groups = groups;
-        }
-
-        public int getTotGroups() {
-            return totGroups;
-        }
-
-        public void setTotGroups(final int totGroups) {
-            this.totGroups = totGroups;
-        }
-
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
deleted file mode 100644
index 12bd30f..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.enduser.SyncopeWebApplication;
-import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.adapters.PlatformInfoAdapter;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.client.enduser.model.CustomAttributesInfo;
-import org.apache.syncope.client.enduser.util.SaltGenerator;
-import org.apache.wicket.request.resource.IResource;
-import org.apache.wicket.util.cookies.CookieUtils;
-
-@Resource(key = "info", path = "/api/info")
-public class InfoResource extends BaseResource {
-
-    private static final long serialVersionUID = 6453101466981543020L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-        ResourceResponse response = new ResourceResponse();
-        response.setContentType(MediaType.APPLICATION_JSON);
-
-        try {
-            final CookieUtils sessionCookieUtils = SyncopeEnduserSession.get().getCookieUtils();
-            // set XSRF_TOKEN cookie
-            if (!SyncopeEnduserSession.get().isXsrfTokenGenerated() && (sessionCookieUtils.getCookie(
-                    SyncopeEnduserConstants.XSRF_COOKIE) == null || StringUtils.isBlank(
-                            sessionCookieUtils.getCookie(SyncopeEnduserConstants.XSRF_COOKIE).getValue()))) {
-                LOG.debug("Set XSRF-TOKEN cookie");
-                SyncopeEnduserSession.get().setXsrfTokenGenerated(true);
-                sessionCookieUtils.save(SyncopeEnduserConstants.XSRF_COOKIE,
-                        SaltGenerator.generate(SyncopeEnduserSession.get().getId()));
-            }
-            response.setTextEncoding(StandardCharsets.UTF_8.name());
-
-            response.setWriteCallback(new WriteCallback() {
-
-                @Override
-                public void writeData(final IResource.Attributes attributes) throws IOException {
-                    Map<String, CustomAttributesInfo> customFormAttributes =
-                            SyncopeWebApplication.get().getCustomFormAttributes();
-                    attributes.getResponse().write(
-                            MAPPER.writeValueAsString(
-                                    PlatformInfoAdapter.toPlatformInfoRequest(
-                                            SyncopeEnduserSession.get().getPlatformInfo(),
-                                            customFormAttributes == null
-                                                    ? new HashMap<>()
-                                                    : customFormAttributes)));
-                }
-            });
-            response.setStatusCode(Response.Status.OK.getStatusCode());
-        } catch (Exception e) {
-            LOG.error("Error retrieving syncope info", e);
-            response.setError(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-
-        return response;
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
deleted file mode 100644
index 8e4086e..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.enduser.SyncopeWebApplication;
-import org.apache.syncope.client.enduser.model.Credentials;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.request.resource.IResource;
-import org.apache.wicket.util.io.IOUtils;
-
-@Resource(key = "login", path = "/api/login")
-public class LoginResource extends BaseResource {
-
-    private static final long serialVersionUID = -7720997467070461915L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-        ResourceResponse response = new AbstractResource.ResourceResponse();
-        response.setContentType(MediaType.TEXT_PLAIN);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            Credentials credentials = MAPPER.readValue(
-                    IOUtils.toString(request.getInputStream()), Credentials.class);
-            final String username = credentials.getUsername();
-            final String password = credentials.getPassword().isEmpty() ? null : credentials.getPassword();
-
-            LOG.debug("Enduser login, user: {}", username);
-
-            if (StringUtils.isBlank(username)) {
-                LOG.error("Could not read credentials from request: username is blank!");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(),
-                        "ErrorMessage{{ Could not read credentials from request: username is blank! }}");
-            } else if (!SyncopeWebApplication.get().getAdminUser().equalsIgnoreCase(username)
-                    && SyncopeEnduserSession.get().authenticate(username, password)) {
-                // user has been authenticated successfully
-                response.setTextEncoding(StandardCharsets.UTF_8.name());
-                response.setWriteCallback(new WriteCallback() {
-
-                    @Override
-                    public void writeData(final Attributes attributes) throws IOException {
-                        attributes.getResponse().write(username);
-                    }
-                });
-                response.setStatusCode(Response.Status.OK.getStatusCode());
-            } else {
-                // not authenticated
-                response.setError(Response.Status.UNAUTHORIZED.getStatusCode(),
-                        "ErrorMessage{{ Username or password are incorrect }}");
-            }
-        } catch (Exception e) {
-            LOG.error("Could not read credentials from request", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-        return response;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/RealmResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/RealmResource.java
deleted file mode 100644
index 8c6d74a..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/RealmResource.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.common.lib.to.RealmTO;
-import org.apache.syncope.common.rest.api.service.RealmService;
-import org.apache.wicket.request.resource.AbstractResource;
-
-@Resource(key = "realms", path = "/api/realms")
-public class RealmResource extends BaseResource {
-
-    private static final long serialVersionUID = 7475706378304995200L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final Attributes attributes) {
-        LOG.debug("Search all available realms");
-
-        ResourceResponse response = new ResourceResponse();
-        response.setContentType(MediaType.APPLICATION_JSON);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            final List<RealmTO> realmTOs = SyncopeEnduserSession.get().getService(RealmService.class).list();
-
-            response.setTextEncoding(StandardCharsets.UTF_8.name());
-
-            response.setWriteCallback(new AbstractResource.WriteCallback() {
-
-                @Override
-                public void writeData(final Attributes attributes) throws IOException {
-                    attributes.getResponse().write(MAPPER.writeValueAsString(realmTOs));
-                }
-            });
-            response.setStatusCode(Response.Status.OK.getStatusCode());
-        } catch (Exception e) {
-            LOG.error("Error retrieving available realms", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-
-        return response;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
deleted file mode 100644
index 8ebee91..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.enduser.SyncopeWebApplication;
-import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.client.enduser.model.CustomAttribute;
-import org.apache.syncope.client.enduser.model.CustomAttributesInfo;
-import org.apache.syncope.client.enduser.model.CustomTemplateInfo;
-import org.apache.syncope.client.enduser.model.SchemaResponse;
-import org.apache.syncope.common.lib.to.SchemaTO;
-import org.apache.syncope.common.lib.to.TypeExtensionTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.rest.api.beans.SchemaQuery;
-import org.apache.syncope.common.rest.api.service.SchemaService;
-import org.apache.syncope.common.rest.api.service.SyncopeService;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.request.resource.IResource;
-
-@Resource(key = "schemas", path = "/api/schemas")
-public class SchemaResource extends BaseResource {
-
-    private static final long serialVersionUID = 6453101466981543020L;
-
-    @Override
-    protected AbstractResource.ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-        LOG.debug("Search all {} any type kind related schemas", AnyTypeKind.USER.name());
-
-        ResourceResponse response = new AbstractResource.ResourceResponse();
-        response.setContentType(MediaType.APPLICATION_JSON);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            List<String> classes = Collections.emptyList();
-
-            String group = attributes.getParameters().get("group").toString();
-            if (group != null) {
-                try {
-                    TypeExtensionTO typeExt = SyncopeEnduserSession.get().
-                            getService(SyncopeService.class).readUserTypeExtension(group);
-                    classes = typeExt.getAuxClasses();
-                } catch (Exception e) {
-                    LOG.error("Could not read User type extension for Group {}", group);
-                }
-            } else {
-                String anyTypeClass = attributes.getParameters().get("anyTypeClass").toString();
-                if (anyTypeClass != null) {
-                    classes = Collections.singletonList(anyTypeClass);
-                } else {
-                    classes = SyncopeEnduserSession.get().
-                            getService(SyncopeService.class).platform().getUserClasses();
-                }
-            }
-
-            // USER from customization, if empty or null ignore it, use it to filter attributes otherwise
-            Map<String, CustomAttributesInfo> customFormAttributes =
-                    SyncopeWebApplication.get().getCustomFormAttributes();
-            CustomTemplateInfo customTemplate =
-                    SyncopeWebApplication.get().getCustomTemplate();
-
-            SchemaService schemaService = SyncopeEnduserSession.get().getService(SchemaService.class);
-            final List<SchemaTO> plainSchemas = classes.isEmpty()
-                    ? Collections.<SchemaTO>emptyList()
-                    : customFormAttributes == null
-                    || customFormAttributes.isEmpty()
-                    || customFormAttributes.get(SchemaType.PLAIN.name()) == null
-                    ? schemaService.search(
-                            new SchemaQuery.Builder().type(SchemaType.PLAIN).anyTypeClasses(classes).build())
-                    : customTemplate.getWizard().getSteps().containsKey("plainSchemas")
-                    ? customizeSchemas(schemaService.search(new SchemaQuery.Builder().type(SchemaType.PLAIN).
-                            anyTypeClasses(classes).build()), group,
-                            customFormAttributes.get(SchemaType.PLAIN.name()).getAttributes())
-                    : Collections.<SchemaTO>emptyList();
-            final List<SchemaTO> derSchemas = classes.isEmpty()
-                    ? Collections.<SchemaTO>emptyList()
-                    : customFormAttributes == null
-                    || customFormAttributes.isEmpty()
-                    || customFormAttributes.get(SchemaType.DERIVED.name()) == null
-                    ? schemaService.search(
-                            new SchemaQuery.Builder().type(SchemaType.DERIVED).anyTypeClasses(classes).build())
-                    : customTemplate.getWizard().getSteps().containsKey("derivedSchemas")
-                    ? customizeSchemas(schemaService.search(new SchemaQuery.Builder().type(SchemaType.DERIVED).
-                            anyTypeClasses(classes).build()), group,
-                            customFormAttributes.get(SchemaType.DERIVED.name()).getAttributes())
-                    : Collections.<SchemaTO>emptyList();
-            final List<SchemaTO> virSchemas = classes.isEmpty()
-                    ? Collections.<SchemaTO>emptyList()
-                    : customFormAttributes == null
-                    || customFormAttributes.isEmpty()
-                    || customFormAttributes.get(SchemaType.VIRTUAL.name()) == null
-                    ? schemaService.search(
-                            new SchemaQuery.Builder().type(SchemaType.VIRTUAL).anyTypeClasses(classes).build())
-                    : customTemplate.getWizard().getSteps().containsKey("virtualSchemas")
-                    ? customizeSchemas(schemaService.search(new SchemaQuery.Builder().type(SchemaType.VIRTUAL).
-                            anyTypeClasses(classes).build()), group,
-                            customFormAttributes.get(SchemaType.VIRTUAL.name()).getAttributes())
-                    : Collections.<SchemaTO>emptyList();
-
-            if (group != null) {
-                plainSchemas.forEach(schema -> {
-                    schema.setKey(compositeSchemaKey(group, schema.getKey()));
-                });
-                derSchemas.forEach(schema -> {
-                    schema.setKey(compositeSchemaKey(group, schema.getKey()));
-                });
-                virSchemas.forEach(schema -> {
-                    schema.setKey(compositeSchemaKey(group, schema.getKey()));
-                });
-            }
-
-            response.setTextEncoding(StandardCharsets.UTF_8.name());
-
-            response.setWriteCallback(new AbstractResource.WriteCallback() {
-
-                @Override
-                public void writeData(final IResource.Attributes attributes) throws IOException {
-                    attributes.getResponse().write(MAPPER.writeValueAsString(new SchemaResponse().
-                            plainSchemas(plainSchemas).
-                            derSchemas(derSchemas).
-                            virSchemas(virSchemas)));
-                }
-            });
-            response.setStatusCode(Response.Status.OK.getStatusCode());
-        } catch (Exception e) {
-            LOG.error("Error retrieving {} any type kind related schemas", AnyTypeKind.USER.name(), e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-        return response;
-    }
-
-    private List<SchemaTO> customizeSchemas(
-            final List<SchemaTO> schemaTOs,
-            final String groupParam,
-            final Map<String, CustomAttribute> customFormAttributes) {
-        if (customFormAttributes.isEmpty()) {
-            return schemaTOs;
-        }
-        final boolean isGroupBlank = StringUtils.isBlank(groupParam);
-
-        schemaTOs.removeAll(schemaTOs.stream().
-                filter(schema -> !customFormAttributes.containsKey(isGroupBlank
-                ? schema.getKey()
-                : compositeSchemaKey(groupParam, schema.getKey()))).
-                collect(Collectors.toSet()));
-
-        Collections.sort(schemaTOs, (schemaTO1, schemaTO2) -> {
-            List<String> order = new ArrayList<>(customFormAttributes.keySet());
-            return order.indexOf(isGroupBlank
-                    ? schemaTO1.getKey()
-                    : compositeSchemaKey(groupParam, schemaTO1.getKey()))
-                    - order.indexOf(isGroupBlank
-                            ? schemaTO2.getKey()
-                            : compositeSchemaKey(groupParam, schemaTO2.getKey()));
-        });
-
-        return schemaTOs;
-    }
-
-    private String compositeSchemaKey(final String prefix, final String schemaKey) {
-        return prefix + SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR + schemaKey;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionByUsernameResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionByUsernameResource.java
deleted file mode 100644
index 419d51b..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionByUsernameResource.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.common.lib.to.SecurityQuestionTO;
-import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.request.resource.IResource;
-import org.apache.wicket.util.string.StringValue;
-
-@Resource(key = "securityQuestionByUsername", path = "/api/securityQuestions/byUser/${username}")
-public class SecurityQuestionByUsernameResource extends BaseResource {
-
-    private static final long serialVersionUID = 6453101466981543020L;
-
-    @Override
-    protected AbstractResource.ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-        LOG.debug("List available security questions");
-
-        ResourceResponse response = new AbstractResource.ResourceResponse();
-        response.setContentType(MediaType.APPLICATION_JSON);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            PageParameters parameters = attributes.getParameters();
-            StringValue username = parameters.get("username");
-            if (!username.isEmpty()) {
-                final SecurityQuestionTO securityQuestionTO = SyncopeEnduserSession.get().
-                        getService(SecurityQuestionService.class).readByUser(username.toString());
-                response.setWriteCallback(new AbstractResource.WriteCallback() {
-
-                    @Override
-                    public void writeData(final IResource.Attributes attributes) throws IOException {
-                        attributes.getResponse().write(MAPPER.writeValueAsString(securityQuestionTO));
-                    }
-                });
-            }
-
-            response.setContentType(MediaType.APPLICATION_JSON);
-            response.setTextEncoding(StandardCharsets.UTF_8.name());
-            response.setStatusCode(Response.Status.OK.getStatusCode());
-        } catch (Exception e) {
-            LOG.error("Error retrieving security questions", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-
-        return response;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionsResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionsResource.java
deleted file mode 100644
index 201da2d..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionsResource.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.common.lib.to.SecurityQuestionTO;
-import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.request.resource.IResource;
-
-@Resource(key = "securityQuestions", path = "/api/securityQuestions")
-public class SecurityQuestionsResource extends BaseResource {
-
-    private static final long serialVersionUID = 6453101466981543020L;
-
-    @Override
-    protected AbstractResource.ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-        LOG.debug("List available security questions");
-
-        AbstractResource.ResourceResponse response = new AbstractResource.ResourceResponse();
-        response.setContentType(MediaType.APPLICATION_JSON);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            final List<SecurityQuestionTO> securityQuestionTOs = SyncopeEnduserSession.get().
-                    getService(SecurityQuestionService.class).list();
-            response.setWriteCallback(new AbstractResource.WriteCallback() {
-
-                @Override
-                public void writeData(final IResource.Attributes attributes) throws IOException {
-                    attributes.getResponse().write(MAPPER.writeValueAsString(securityQuestionTOs));
-                }
-            });
-
-            response.setTextEncoding(StandardCharsets.UTF_8.name());
-            response.setStatusCode(Response.Status.OK.getStatusCode());
-        } catch (Exception e) {
-            LOG.error("Error retrieving security questions", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-
-        return response;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserClassesResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserClassesResource.java
deleted file mode 100644
index 088b35b..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserClassesResource.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.common.rest.api.service.SyncopeService;
-import org.apache.wicket.request.resource.AbstractResource;
-
-@Resource(key = "anyType", path = "/api/userClasses")
-public class UserClassesResource extends BaseResource {
-
-    private static final long serialVersionUID = 7475706378304995200L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final Attributes attributes) {
-        LOG.debug("Get USER classes");
-
-        ResourceResponse response = new ResourceResponse();
-        response.setContentType(MediaType.APPLICATION_JSON);
-        try {
-
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            final List<String> userClasses = SyncopeEnduserSession.get().
-                    getService(SyncopeService.class).platform().getUserClasses();
-
-            response.setTextEncoding(StandardCharsets.UTF_8.name());
-            response.setWriteCallback(new AbstractResource.WriteCallback() {
-
-                @Override
-                public void writeData(final Attributes attributes) throws IOException {
-                    attributes.getResponse().write(MAPPER.writeValueAsString(userClasses));
-                }
-            });
-            response.setStatusCode(Response.Status.OK.getStatusCode());
-        } catch (Exception e) {
-            LOG.error("Error retrieving available any type details", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-        return response;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfChangePassword.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfChangePassword.java
deleted file mode 100644
index e18cd28..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfChangePassword.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.common.rest.api.service.UserSelfService;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.request.resource.IResource;
-
-@Resource(key = "userSelfChangePassword", path = "/api/self/changePassword")
-public class UserSelfChangePassword extends BaseResource {
-
-    private static final long serialVersionUID = -2721621682300247583L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-        ResourceResponse response = new AbstractResource.ResourceResponse();
-        response.setContentType(MediaType.APPLICATION_JSON);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            Map<String, String[]> parameters = request.getParameterMap();
-
-            if (parameters.get("newPassword") == null || parameters.get("newPassword").length == 0) {
-                throw new Exception("A new correct password should be provided");
-            }
-            SyncopeEnduserSession.get().getService(UserSelfService.class).
-                    mustChangePassword(parameters.get("newPassword")[0]);
-
-            response.setTextEncoding(StandardCharsets.UTF_8.name());
-            response.setStatusCode(Response.Status.NO_CONTENT.getStatusCode());
-        } catch (final Exception e) {
-            LOG.error("Error while updating user", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-        return response;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfConfirmPasswordReset.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfConfirmPasswordReset.java
deleted file mode 100644
index 8bb15c2..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfConfirmPasswordReset.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.util.Map;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.common.rest.api.service.UserSelfService;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.request.resource.IResource;
-
-@Resource(key = "userSelfConfirmPasswordReset", path = "/api/self/confirmPasswordReset")
-public class UserSelfConfirmPasswordReset extends BaseUserSelfResource {
-
-    private static final long serialVersionUID = -2721621682300247583L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-        ResourceResponse response = new AbstractResource.ResourceResponse();
-        response.setContentType(MediaType.TEXT_PLAIN);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            Map<String, String[]> parameters = request.getParameterMap();
-            String token;
-            if (parameters.get("token") == null || parameters.get("token").length == 0) {
-                throw new Exception("A valid token should be provided");
-            } else {
-                token = parameters.get("token")[0];
-            }
-
-            if (parameters.get("newPassword") == null || parameters.get("newPassword").length == 0) {
-                throw new Exception("A new correct password should be provided");
-            }
-            SyncopeEnduserSession.get().getService(UserSelfService.class).
-                    confirmPasswordReset(token, parameters.get("newPassword")[0]);
-
-            buildResponse(response, Response.Status.OK.getStatusCode(),
-                    "Password successfully updated");
-        } catch (final Exception e) {
-            LOG.error("Error while updating user", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-        return response;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
deleted file mode 100644
index 4e8aea6..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.util.HashSet;
-import java.util.Set;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.lang3.SerializationUtils;
-import org.apache.syncope.client.enduser.SyncopeWebApplication;
-import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.client.enduser.util.Validation;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.request.UserCR;
-import org.apache.syncope.common.lib.Attr;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.rest.api.service.UserSelfService;
-
-@Resource(key = "userSelfCreate", path = "/api/self/create")
-public class UserSelfCreateResource extends BaseUserSelfResource {
-
-    private static final long serialVersionUID = -2721621682300247583L;
-
-    private boolean isSelfRegistrationAllowed() {
-        Boolean result = null;
-        try {
-            result = SyncopeEnduserSession.get().getPlatformInfo().isSelfRegAllowed();
-        } catch (SyncopeClientException e) {
-            LOG.error("While seeking if self registration is allowed", e);
-        }
-
-        return result == null
-                ? false
-                : result;
-    }
-
-    @Override
-    protected ResourceResponse newResourceResponse(final Attributes attributes) {
-        ResourceResponse response = new ResourceResponse();
-        response.setContentType(MediaType.TEXT_PLAIN);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN is not matching");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN is not matching");
-                return response;
-            }
-
-            String jsonString = request.getReader().readLine();
-            final UserTO userTO = MAPPER.readValue(jsonString, UserTO.class);
-
-            if (!captchaCheck(
-                    request.getHeader("captcha"),
-                    request.getSession().getAttribute(SyncopeEnduserConstants.CAPTCHA_SESSION_KEY))) {
-
-                throw new IllegalArgumentException("Entered captcha is not matching");
-            }
-
-            if (isSelfRegistrationAllowed() && userTO != null) {
-                LOG.debug("User self registration request for [{}]", userTO.getUsername());
-                LOG.trace("Request is [{}]", userTO);
-
-                // check if request is compliant with customization form rules
-                if (Validation.isCompliant(userTO,
-                        SyncopeWebApplication.get().getCustomFormAttributes(), true)) {
-
-                    // 1. membership attributes management
-                    Set<Attr> membAttrs = new HashSet<>();
-                    userTO.getPlainAttrs().stream().
-                            filter(attr -> (attr.getSchema().
-                            contains(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR))).
-                            forEach(attr -> {
-                                String[] simpleAttrs = attr.getSchema().split(
-                                        SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR);
-                                MembershipTO membership = userTO.getMemberships().stream().
-                                        filter(memb -> simpleAttrs[0].equals(memb.getGroupName())).
-                                        findFirst().orElse(null);
-                                if (membership == null) {
-                                    membership = new MembershipTO.Builder(null).groupName(simpleAttrs[0]).build();
-                                    userTO.getMemberships().add(membership);
-                                }
-
-                                Attr clone = SerializationUtils.clone(attr);
-                                clone.setSchema(simpleAttrs[1]);
-                                membership.getPlainAttrs().add(clone);
-                                membAttrs.add(attr);
-                            });
-                    userTO.getPlainAttrs().removeAll(membAttrs);
-
-                    // 2. millis -> Date conversion for PLAIN attributes of USER and its MEMBERSHIPS
-                    SyncopeEnduserSession.get().getDatePlainSchemas().stream().map(plainSchema -> {
-                        millisToDate(userTO.getPlainAttrs(), plainSchema);
-                        return plainSchema;
-                    }).forEach(plainSchema -> {
-                        userTO.getMemberships().forEach(membership -> {
-                            millisToDate(membership.getPlainAttrs(), plainSchema);
-                        });
-                    });
-
-                    membAttrs.clear();
-                    userTO.getDerAttrs().stream().
-                            filter(attr -> (attr.getSchema().
-                            contains(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR))).
-                            forEach(attr -> {
-                                String[] simpleAttrs = attr.getSchema().split(
-                                        SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR);
-                                MembershipTO membership = userTO.getMemberships().stream().
-                                        filter(memb -> simpleAttrs[0].equals(memb.getGroupName())).
-                                        findFirst().orElse(null);
-                                if (membership == null) {
-                                    membership = new MembershipTO.Builder(null).groupName(simpleAttrs[0]).build();
-                                    userTO.getMemberships().add(membership);
-                                }
-
-                                Attr clone = SerializationUtils.clone(attr);
-                                clone.setSchema(simpleAttrs[1]);
-                                membership.getDerAttrs().add(clone);
-                                membAttrs.add(attr);
-                            });
-                    userTO.getDerAttrs().removeAll(membAttrs);
-
-                    membAttrs.clear();
-                    userTO.getVirAttrs().stream().
-                            filter(attr -> (attr.getSchema().
-                            contains(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR))).
-                            forEach(attr -> {
-                                String[] simpleAttrs = attr.getSchema().split(
-                                        SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR);
-                                MembershipTO membership = userTO.getMemberships().stream().
-                                        filter(memb -> simpleAttrs[0].equals(memb.getGroupName())).
-                                        findFirst().orElse(null);
-                                if (membership == null) {
-                                    membership = new MembershipTO.Builder(null).groupName(simpleAttrs[0]).build();
-                                    userTO.getMemberships().add(membership);
-                                }
-
-                                Attr clone = SerializationUtils.clone(attr);
-                                clone.setSchema(simpleAttrs[1]);
-                                membership.getVirAttrs().add(clone);
-                                membAttrs.add(attr);
-                            });
-                    userTO.getVirAttrs().removeAll(membAttrs);
-
-                    LOG.debug("Received user self registration request for user: [{}]", userTO.getUsername());
-                    LOG.trace("Received user self registration request is: [{}]", userTO);
-
-                    // adapt request and create user
-                    UserCR req = new UserCR.Builder(userTO.getRealm(), userTO.getUsername()).
-                            password(userTO.getPassword()).
-                            mustChangePassword(userTO.isMustChangePassword()).
-                            securityQuestion(userTO.getSecurityQuestion()).
-                            securityAnswer(userTO.getSecurityAnswer()).
-                            auxClasses(userTO.getAuxClasses()).
-                            plainAttrs(userTO.getPlainAttrs()).
-                            virAttrs(userTO.getVirAttrs()).
-                            memberships(userTO.getMemberships()).
-                            relationships(userTO.getRelationships()).
-                            roles(userTO.getRoles()).
-                            resources(userTO.getResources()).
-                            build();
-                    Response res = SyncopeEnduserSession.get().getService(UserSelfService.class).create(req);
-
-                    buildResponse(response, res.getStatus(),
-                            Response.Status.Family.SUCCESSFUL.equals(res.getStatusInfo().getFamily())
-                            ? "User[ " + userTO.getUsername() + "] successfully created"
-                            : "ErrorMessage{{ " + res.getStatusInfo().getReasonPhrase() + " }}");
-                } else {
-                    LOG.warn(
-                            "Incoming create request [{}] is not compliant with form customization rules. "
-                            + "Create NOT allowed", userTO.getUsername());
-                    buildResponse(response, Response.Status.OK.getStatusCode(),
-                            "User: " + userTO.getUsername() + " successfully created");
-                }
-            } else {
-                response.setError(Response.Status.FORBIDDEN.getStatusCode(), new StringBuilder().
-                        append("ErrorMessage{{").append(userTO == null
-                        ? "Request received is not valid }}"
-                        : "Self registration not allowed }}").toString());
-            }
-        } catch (Exception e) {
-            LOG.error("Unable to create userTO", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(),
-                    new StringBuilder().
-                            append("ErrorMessage{{ ").
-                            append(e.getMessage()).
-                            append(" }}").
-                            toString());
-        }
-        return response;
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfIsLogged.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfIsLogged.java
deleted file mode 100644
index e153b81..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfIsLogged.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.io.IOException;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.wicket.request.resource.IResource;
-
-@Resource(key = "userSelfIsLogged", path = "/api/self/islogged")
-public class UserSelfIsLogged extends BaseResource {
-
-    private static final long serialVersionUID = -8716361267586908871L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final Attributes attributes) {
-        LOG.debug("Checking if user is authenticated");
-
-        ResourceResponse response = new ResourceResponse();
-        response.setContentType(MediaType.TEXT_PLAIN);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            response.setWriteCallback(new WriteCallback() {
-
-                @Override
-                public void writeData(final IResource.Attributes attributes) throws IOException {
-                    attributes.getResponse().write(
-                            Boolean.toString(SyncopeEnduserSession.get().isAuthenticated()));
-                }
-            });
-            response.setStatusCode(Response.Status.OK.getStatusCode());
-        } catch (Exception e) {
-            LOG.error("Could not read credentials from request", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-        return response;
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfPasswordReset.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfPasswordReset.java
deleted file mode 100644
index 9fd42e9..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfPasswordReset.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.util.Map;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.common.rest.api.service.UserSelfService;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.request.resource.IResource;
-
-@Resource(key = "userSelfPasswordReset", path = "/api/self/requestPasswordReset")
-public class UserSelfPasswordReset extends BaseUserSelfResource {
-
-    private static final long serialVersionUID = -2721621682300247583L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-        ResourceResponse response = new AbstractResource.ResourceResponse();
-        response.setContentType(MediaType.TEXT_PLAIN);
-        String[] usernameParam = { "<unknown>" };
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            Map<String, String[]> parameters = request.getParameterMap();
-            usernameParam = parameters.get("username");
-            if (ArrayUtils.isEmpty(usernameParam)) {
-                throw new Exception("A valid username should be provided");
-            }
-
-            if (request.getHeader("captcha") == null
-                    || !captchaCheck(
-                            request.getHeader("captcha"),
-                            request.getSession().getAttribute(SyncopeEnduserConstants.CAPTCHA_SESSION_KEY))) {
-
-                throw new IllegalArgumentException("Entered captcha is not matching");
-            }
-
-            if (SyncopeEnduserSession.get().getPlatformInfo().isPwdResetRequiringSecurityQuestions()) {
-                String[] securityAnswerParam = parameters.get("securityAnswer");
-                if (ArrayUtils.isEmpty(securityAnswerParam)) {
-                    throw new Exception("A correct security answer should be provided");
-                }
-                SyncopeEnduserSession.get().getService(UserSelfService.class).
-                        requestPasswordReset(usernameParam[0], securityAnswerParam[0]);
-            } else {
-                SyncopeEnduserSession.get().getService(UserSelfService.class).
-                        requestPasswordReset(usernameParam[0], null);
-            }
-        } catch (final Exception e) {
-            LOG.error("Unable to process password reset request", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(),
-                    new StringBuilder().
-                            append("ErrorMessage{{ ").
-                            append(e.getMessage()).
-                            append(" }}").
-                            toString());
-        }
-
-        buildResponse(response, Response.Status.OK.getStatusCode(),
-                "Password reset request sent for user " + usernameParam[0]);
-        return response;
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
deleted file mode 100644
index 3425ca0..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.lang3.SerializationUtils;
-import org.apache.syncope.client.enduser.SyncopeWebApplication;
-import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.client.enduser.model.CustomAttributesInfo;
-import org.apache.syncope.common.lib.Attr;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.PlainSchemaTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.request.resource.IResource;
-
-@Resource(key = "userSelfRead", path = "/api/self/read")
-public class UserSelfReadResource extends BaseUserSelfResource {
-
-    private static final long serialVersionUID = -9184809392631523912L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-        LOG.debug("Requested user self information");
-
-        ResourceResponse response = new AbstractResource.ResourceResponse();
-        response.setContentType(MediaType.APPLICATION_JSON);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            UserTO userTO = SerializationUtils.clone(SyncopeEnduserSession.get().getSelfTO());
-
-            // 1. Date -> millis conversion for PLAIN MEMBERSHIPS attributes of USER
-            for (PlainSchemaTO plainSchema : SyncopeEnduserSession.get().getDatePlainSchemas()) {
-                for (MembershipTO membership : userTO.getMemberships()) {
-                    dateToMillis(membership.getPlainAttrs(), plainSchema);
-                }
-            }
-
-            // 2. membership attributes management
-            for (MembershipTO membership : userTO.getMemberships()) {
-                String groupName = membership.getGroupName();
-                membership.getPlainAttrs().stream().map(attr -> {
-                    attr.setSchema(groupName.concat(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR).
-                            concat(attr.getSchema()));
-                    return attr;
-                }).forEachOrdered(attr -> {
-                    userTO.getPlainAttrs().add(attr);
-                });
-                membership.getPlainAttrs().clear();
-                membership.getDerAttrs().stream().map(attr -> {
-                    attr.setSchema(groupName.concat(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR).
-                            concat(attr.getSchema()));
-                    return attr;
-                }).forEachOrdered(attr -> {
-                    userTO.getDerAttrs().add(attr);
-                });
-                membership.getDerAttrs().clear();
-                membership.getVirAttrs().stream().map((attr) -> {
-                    attr.setSchema(groupName.concat(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR).
-                            concat(attr.getSchema()));
-                    return attr;
-                }).forEachOrdered(attr -> {
-                    userTO.getVirAttrs().add(attr);
-                });
-                membership.getVirAttrs().clear();
-            }
-            // USER from customization, if empty or null ignore it, use it to filter attributes otherwise
-            applyFromCustomization(userTO, SyncopeWebApplication.get().getCustomFormAttributes());
-
-            // 1.1 Date -> millis conversion for PLAIN attributes of USER
-            for (PlainSchemaTO plainSchema : SyncopeEnduserSession.get().getDatePlainSchemas()) {
-                dateToMillis(userTO.getPlainAttrs(), plainSchema);
-            }
-
-            final String selfTOJson = MAPPER.writeValueAsString(userTO);
-            response.setContentType(MediaType.APPLICATION_JSON);
-            response.setTextEncoding(StandardCharsets.UTF_8.name());
-
-            response.setWriteCallback(new WriteCallback() {
-
-                @Override
-                public void writeData(final Attributes attributes) throws IOException {
-                    attributes.getResponse().write(selfTOJson);
-                }
-            });
-            response.setStatusCode(Response.Status.OK.getStatusCode());
-        } catch (Exception e) {
-            LOG.error("Error retrieving selfTO", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
-                    .append("ErrorMessage{{ ")
-                    .append(e.getMessage())
-                    .append(" }}")
-                    .toString());
-        }
-        return response;
-    }
-
-    private void applyFromCustomization(final UserTO userTO,
-            final Map<String, CustomAttributesInfo> customFormAttributes) {
-        if (customFormAttributes != null && !customFormAttributes.isEmpty()) {
-            // filter PLAIN attributes
-            customizeAttrs(userTO.getPlainAttrs(), customFormAttributes.get(SchemaType.PLAIN.name()));
-            // filter DERIVED attributes
-            customizeAttrs(userTO.getDerAttrs(), customFormAttributes.get(SchemaType.DERIVED.name()));
-            // filter VIRTUAL attributes
-            customizeAttrs(userTO.getVirAttrs(), customFormAttributes.get(SchemaType.VIRTUAL.name()));
-        }
-    }
-
-    private void customizeAttrs(final Set<Attr> attrs, final CustomAttributesInfo customAttributesInfo) {
-        if (customAttributesInfo != null
-                && !customAttributesInfo.getAttributes().isEmpty()) {
-
-            attrs.removeAll(attrs.stream().
-                    filter(attr -> !customAttributesInfo.getAttributes().containsKey(attr.getSchema())).
-                    collect(Collectors.toList()));
-            attrs.clear();
-        }
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
deleted file mode 100644
index 897cb25..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.resources;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.lang3.SerializationUtils;
-import org.apache.syncope.client.enduser.SyncopeWebApplication;
-import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.client.enduser.annotations.Resource;
-import org.apache.syncope.client.enduser.model.CustomAttributesInfo;
-import org.apache.syncope.client.enduser.util.Validation;
-import org.apache.syncope.common.lib.AnyOperations;
-import org.apache.syncope.common.lib.EntityTOUtils;
-import org.apache.syncope.common.lib.request.UserUR;
-import org.apache.syncope.common.lib.Attr;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.rest.api.service.UserSelfService;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.request.resource.IResource;
-
-@Resource(key = "userSelfUpdate", path = "/api/self/update")
-public class UserSelfUpdateResource extends BaseUserSelfResource {
-
-    private static final long serialVersionUID = -2721621682300247583L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-        ResourceResponse response = new AbstractResource.ResourceResponse();
-        response.setContentType(MediaType.TEXT_PLAIN);
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-            if (!xsrfCheck(request)) {
-                LOG.error("XSRF TOKEN does not match");
-                response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
-                return response;
-            }
-
-            if (!captchaCheck(
-                    request.getHeader("captcha"),
-                    request.getSession().getAttribute(SyncopeEnduserConstants.CAPTCHA_SESSION_KEY))) {
-
-                throw new IllegalArgumentException("Entered captcha is not matching");
-            }
-
-            UserTO userTO = MAPPER.readValue(request.getReader().readLine(), UserTO.class);
-            Map<String, CustomAttributesInfo> customFormAttributes =
-                    SyncopeWebApplication.get().getCustomFormAttributes();
-
-            // check if request is compliant with customization form rules
-            if (Validation.isCompliant(userTO, customFormAttributes, false)) {
-                // 1. membership attributes management
-                Set<Attr> membAttrs = new HashSet<>();
-                userTO.getPlainAttrs().stream().
-                        filter(attr -> (attr.getSchema().contains(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR))).
-                        forEach(attr -> {
-                            String[] simpleAttrs = attr.getSchema().split(
-                                    SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR);
-                            MembershipTO membership = userTO.getMemberships().stream().
-                                    filter(item -> simpleAttrs[0].equals(item.getGroupName())).
-                                    findFirst().orElse(null);
-                            if (membership == null) {
-                                membership = new MembershipTO.Builder(null).groupName(simpleAttrs[0]).build();
-                                userTO.getMemberships().add(membership);
-                            }
-                            Attr clone = SerializationUtils.clone(attr);
-                            clone.setSchema(simpleAttrs[1]);
-                            membership.getPlainAttrs().add(clone);
-                            membAttrs.add(attr);
-                        });
-                userTO.getPlainAttrs().removeAll(membAttrs);
-
-                // 2. millis -> Date conversion for PLAIN attributes of USER and its MEMBERSHIPS
-                SyncopeEnduserSession.get().getDatePlainSchemas().stream().
-                        map(plainSchema -> {
-                            millisToDate(userTO.getPlainAttrs(), plainSchema);
-                            return plainSchema;
-                        }).forEach(plainSchema -> {
-                    userTO.getMemberships().forEach(membership -> {
-                        millisToDate(membership.getPlainAttrs(), plainSchema);
-                    });
-                });
-
-                membAttrs.clear();
-                userTO.getDerAttrs().stream().
-                        filter(attr -> (attr.getSchema().contains(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR))).
-                        forEach(attr -> {
-                            String[] simpleAttrs = attr.getSchema().split(
-                                    SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR);
-                            MembershipTO membership = userTO.getMemberships().stream().
-                                    filter(item -> simpleAttrs[0].equals(item.getGroupName())).
-                                    findFirst().orElse(null);
-                            if (membership == null) {
-                                membership = new MembershipTO.Builder(null).groupName(simpleAttrs[0]).build();
-                                userTO.getMemberships().add(membership);
-                            }
-                            Attr clone = SerializationUtils.clone(attr);
-                            clone.setSchema(simpleAttrs[1]);
-                            membership.getDerAttrs().add(clone);
-                            membAttrs.add(attr);
-                        });
-                userTO.getDerAttrs().removeAll(membAttrs);
-
-                membAttrs.clear();
-                userTO.getVirAttrs().stream().
-                        filter(attr -> (attr.getSchema().contains(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR))).
-                        forEach((attr) -> {
-                            String[] simpleAttrs = attr.getSchema().split(
-                                    SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR);
-                            MembershipTO membership = userTO.getMemberships().stream().
-                                    filter(item -> simpleAttrs[0].equals(item.getGroupName())).
-                                    findFirst().orElse(null);
-                            if (membership == null) {
-                                membership = new MembershipTO.Builder(null).groupName(simpleAttrs[0]).build();
-                                userTO.getMemberships().add(membership);
-
-                            }
-                            Attr clone = SerializationUtils.clone(attr);
-                            clone.setSchema(simpleAttrs[1]);
-                            membership.getVirAttrs().add(clone);
-                            membAttrs.add(attr);
-                        });
-                userTO.getVirAttrs().removeAll(membAttrs);
-
-                // get old user object from session
-                UserTO selfTO = SyncopeEnduserSession.get().getSelfTO();
-                // align "userTO" and "selfTO" objects
-                if (customFormAttributes != null && !customFormAttributes.isEmpty()) {
-                    completeUserObject(userTO, selfTO);
-                }
-                // create diff patch
-                UserUR userUR = AnyOperations.diff(userTO, selfTO, false);
-                if (userUR.isEmpty()) {
-                    // nothing to do
-                    buildResponse(response,
-                            Response.Status.OK.getStatusCode(),
-                            "No need to update [" + selfTO.getUsername() + "]");
-                } else {
-                    // update user by patch
-                    Response coreResponse = SyncopeEnduserSession.get().
-                            getService(userTO.getETagValue(), UserSelfService.class).update(userUR);
-
-                    buildResponse(response,
-                            coreResponse.getStatus(),
-                            coreResponse.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL
-                            ? "User [" + selfTO.getUsername() + "] successfully updated"
-                            : "ErrorMessage{{ " + coreResponse.getStatusInfo().getReasonPhrase() + " }}");
-                }
-            } else {
-                LOG.warn(
-                        "Incoming update request [{}] is not compliant with form customization rules."
-                        + " Update NOT allowed", userTO.getUsername());
-                buildResponse(response, Response.Status.OK.getStatusCode(),
-                        "User: " + userTO.getUsername() + " successfully created");
-            }
-        } catch (final Exception e) {
-            LOG.error("Error while updating user", e);
-            response.setError(Response.Status.BAD_REQUEST.getStatusCode(),
-                    new StringBuilder().
-                            append("ErrorMessage{{ ").
-                            append(e.getMessage()).
-                            append(" }}").
-                            toString());
-        }
-        return response;
-    }
-
-    private void completeUserObject(final UserTO userTO, final UserTO selfTO) {
-        // memberships plain and virtual attrs
-        userTO.getMemberships().forEach(updatedTOMemb -> {
-            selfTO.getMemberships().stream().
-                    filter(oldTOMemb -> updatedTOMemb.getGroupKey().equals(oldTOMemb.getGroupKey())).
-                    findFirst().ifPresent(oldTOMatchedMemb -> {
-                        if (!updatedTOMemb.getPlainAttrs().isEmpty()) {
-                            completeAttrs(updatedTOMemb.getPlainAttrs(), oldTOMatchedMemb.getPlainAttrs());
-                        }
-                        if (!updatedTOMemb.getVirAttrs().isEmpty()) {
-                            completeAttrs(updatedTOMemb.getVirAttrs(), oldTOMatchedMemb.getVirAttrs());
-                        }
-                    });
-        });
-        // plain attrs
-        completeAttrs(userTO.getPlainAttrs(), selfTO.getPlainAttrs());
-        // virtual attrs
-        completeAttrs(userTO.getVirAttrs(), selfTO.getVirAttrs());
-    }
-
-    private void completeAttrs(final Set<Attr> userTOAttrs, final Set<Attr> selfTOAttrs) {
-        Map<String, Attr> userTOAttrsMap =
-                EntityTOUtils.buildAttrMap(userTOAttrs);
-        selfTOAttrs.stream().
-                filter(selfTOAttr -> (!userTOAttrsMap.containsKey(selfTOAttr.getSchema()))).
-                forEach(selfTOAttr -> {
-                    userTOAttrs.add(selfTOAttr);
-                });
-    }
-
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/util/SaltGenerator.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/util/SaltGenerator.java
deleted file mode 100644
index acb3f13..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/util/SaltGenerator.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.util;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.Base64;
-import javax.xml.bind.DatatypeConverter;
-
-public final class SaltGenerator {
-
-    public static String generate(final String input) {
-        // generate salt
-        byte[] salt = new byte[16];
-        // fill array with random bytes
-        new SecureRandom().nextBytes(salt);
-        // create digest with MD2
-        MessageDigest md;
-        try {
-            md = MessageDigest.getInstance("MD2");
-            return DatatypeConverter.printHexBinary(
-                    md.digest((input + Base64.getMimeEncoder().encodeToString(salt)).getBytes()));
-        } catch (final NoSuchAlgorithmException e) {
-            throw new IllegalArgumentException(e);
-        }
-    }
-
-    private SaltGenerator() {
-        // private constructor for static utility class
-    }
-}
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/util/Validation.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/util/Validation.java
deleted file mode 100644
index 2cb5941..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/util/Validation.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.enduser.util;
-
-import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.enduser.model.CustomAttribute;
-import org.apache.syncope.client.enduser.model.CustomAttributesInfo;
-import org.apache.syncope.client.enduser.model.CustomTemplateInfo;
-import org.apache.syncope.common.lib.EntityTOUtils;
-import org.apache.syncope.common.lib.Attr;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class Validation {
-
-    private static final Logger LOG = LoggerFactory.getLogger(Validation.class);
-
-    public static boolean isCompliant(
-            final UserTO userTO,
-            final Map<String, CustomAttributesInfo> customFormAttributes,
-            final boolean checkDefaultValues) {
-
-        if (customFormAttributes == null || customFormAttributes.isEmpty()) {
-            return true;
-        }
-
-        return validateAttributes(EntityTOUtils.buildAttrMap(userTO.getPlainAttrs()),
-                customFormAttributes.get(SchemaType.PLAIN.name()), checkDefaultValues)
-                && validateAttributes(EntityTOUtils.buildAttrMap(userTO.getDerAttrs()),
-                        customFormAttributes.get(SchemaType.DERIVED.name()), checkDefaultValues)
-                && validateAttributes(EntityTOUtils.buildAttrMap(userTO.getVirAttrs()),
-                        customFormAttributes.get(SchemaType.VIRTUAL.name()), checkDefaultValues);
-    }
-
-    private static boolean validateAttributes(final Map<String, Attr> attrMap,
-            final CustomAttributesInfo customAttrInfo, final boolean checkDefaultValues) {
-
-        return customAttrInfo == null
-                || customAttrInfo.getAttributes().isEmpty()
-                || attrMap.entrySet().stream().allMatch(entry -> {
-                    String schemaKey = entry.getKey();
-                    Attr attrTO = entry.getValue();
-                    CustomAttribute customAttr = customAttrInfo.getAttributes().get(schemaKey);
-                    boolean compliant = customAttr != null && (!checkDefaultValues || isValid(attrTO, customAttr));
-                    if (!compliant) {
-                        LOG.trace("Attribute [{}] or its values [{}] are not allowed by form customization rules",
-                                attrTO.getSchema(), attrTO.getValues());
-                    }
-                    return compliant;
-                });
-    }
-
-    public static boolean validateSteps(final CustomTemplateInfo customTemplateInfo) {
-        return customTemplateInfo != null
-                && StringUtils.isNotBlank(customTemplateInfo.getWizard().getFirstStep())
-                && !customTemplateInfo.getWizard().getSteps().isEmpty();
-
-    }
-
-    public static boolean validateStep(final String stepName, final CustomTemplateInfo customTemplateInfo) {
-        return customTemplateInfo != null
-                && !customTemplateInfo.getWizard().getSteps().isEmpty()
-                && customTemplateInfo.getWizard().getSteps().containsKey(stepName)
-                && StringUtils.isNotBlank(customTemplateInfo.getWizard().getSteps().get(stepName).getUrl());
-
-    }
-
-    private static boolean isValid(final Attr attrTO, final CustomAttribute customAttribute) {
-        return customAttribute.isReadonly()
-                ? attrTO.getValues().stream().allMatch(value -> customAttribute.getDefaultValues().contains(value))
-                : true;
-    }
-
-    private Validation() {
-        // private constructor for static utility class
-    }
-}
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/accessibility.css b/client/enduser/src/main/resources/META-INF/resources/app/css/accessibility.css
deleted file mode 100644
index 04c57a5..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/css/accessibility.css
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-#accessibility {
-  display: block;
-}
-
-.btn-accessibility {
-  position: absolute;
-  right: 0;
-  font-size: 12px;
-  padding: 15px 15px 0 0;
-}
-
-.btn-accessibility i {
-  font-size: 30px;
-}
-
-.btn-accessibility:hover {
-  cursor:pointer;
-}
-
-#change_contrast {
-  top: 0;
-}
-#change_fontSize {
-  top: 40px;
-}
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/accessibility/accessibilityFont.css b/client/enduser/src/main/resources/META-INF/resources/app/css/accessibility/accessibilityFont.css
deleted file mode 100644
index 0f4ef7f..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/css/accessibility/accessibilityFont.css
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-body {
-  font-size: 400%;
-}
-
-.nav-button,
-#login-btn,
-#resetpassword,
-#status-buttons a,
-#login-container a,
-.form-group input,
-.form-group select,
-.panel-title,
-#questionCaptcha,
-#refresh,
-.suggestions,
-.k-notification-wrap,
-.btn-secondary,
-div[role="tablist"] .card-header a,
-div[role="tablist"] .card-collapse,
-ul.pagination,
-.card-body #attribute .fa {
-  font-size: 20px;
-}
-
-.k-picker-wrap {
-  font-size: 17px;
-}
-
-#finish {
-  margin-right: 0;
-}
-#navButtons {
-  padding-right: 20px;
-}
-
-.k-notification-wrap {
-  padding: .1em .2em;
-  line-height: 1.5;
-}
-
-.select2-choices li {
-  line-height: 1 !important;
-}
-
-.select2-choices li .ui-select-match-close {
-  -ms-transform: scale(1.5); /* IE */
-  -moz-transform: scale(1.5); /* FF */
-  -webkit-transform: scale(1.5); /* Safari and Chrome */
-  -o-transform: scale(1.5); /* Opera */
-}
-
-input[type=checkbox] {
-  -ms-transform: scale(2); /* IE */
-  -moz-transform: scale(2); /* FF */
-  -webkit-transform: scale(2); /* Safari and Chrome */
-  -o-transform: scale(2); /* Opera */
-}
-
-/* Workaround - to avoid nav buttons not to be vertically aligned  */
-#navButtons .float-right {
-  font-size: 1px;
-}
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/accessibility/accessibilityHC.css b/client/enduser/src/main/resources/META-INF/resources/app/css/accessibility/accessibilityHC.css
deleted file mode 100644
index 0d9c90d..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/css/accessibility/accessibilityHC.css
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-.btn-accessibility {
-  color: #ffffff;
-}
-
-
-/* EditUser
-============================================================================= */
-html,
-body {
-  height: 100%;
-}
-body {
-  background: #464646;
-}
-
-#form-container .page-header,
-#previous,
-#next,
-#save,
-#finish,
-#resetpassword,
-.modal-content {
-  background: #464646;
-  color: #ffffff;
-}
-
-#previous:hover,
-#next:hover,
-#save:hover,
-#finish:hover,
-#resetpassword:hover {
-  background: #6d6d6d;
-}
-
-#form-container .btn-danger {
-  background-color: #a93f3c;
-  border-color: #ffffff;
-}
-
-
-#form-container,
-#form-container .panel {
-  background-color: #151515;
-  color: #ffffff;
-}
-
-#form-container input, 
-#form-container select,
-#form-container select option,
-#form-container label,
-.k-icon,
-.card-header h5 a {
-  color: #ffffff;
-}
-
-#form-container input:disabled {
-  background: #6d6d6d;
-}
-
-#form-container input,
-#form-container select,
-#form-container select option,
-span.k-datepicker, 
-span.k-timepicker, 
-span.k-datetimepicker, 
-span.k-colorpicker, 
-span.k-numerictextbox, 
-span.k-combobox, 
-span.k-dropdown, 
-.k-toolbar .k-split-button,
-.k-autocomplete.k-state-default, 
-.k-picker-wrap.k-state-default, 
-.k-numeric-wrap.k-state-default, 
-.k-dropdown-wrap.k-state-default {
-  background: #313131;
-}
-
-.card-header,
-.ui-select-choices-row:hover {
-  background-color: #6d6d6d;
-}
-
-.select2-choices,
-.select2-drop-active {
-  background-color: #3e3e3e;
-  color: #ffffff;
-}
-
-.modal-content {
-  border: solid 1px #ffffff;
-}
-
-.btn-warning {
-  background-color: #70420A;
-}
-
-.btn-warning:hover {
-  background-color: #F3AD57;
-  color: #000000;
-}
-
-.btn-primary {
-  background-color: #205179;
-}
-
-.btn-primary:hover {
-  background-color: #2F78B3;
-  color: #ffffff;
-}
-
-.pagination>.disabled>a, .pagination>.disabled>a:focus, .pagination>.disabled>a:hover, .pagination>.disabled>span, 
-.pagination>.disabled>span:focus, .pagination>.disabled>span:hover {
-    color: #ffffff;
-    background-color: #343434;
-    border-color: #ddd;
-}
-
-.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover, .pagination>.active>span, 
-.pagination>.active>span:focus, .pagination>.active>span:hover {
-    color: #ffffff;
-    background-color: #343434;
-    border-color: #ffffff;
-}
-
-.pagination>.active>a, .pagination>.active>span {
-    color: #343434;
-    background-color: #ffffff;
-    border-color: #ffffff;
-}
-
-.pagination>li>a, .pagination>li>span {
-    color: #ffffff;
-    background-color: #343434;
-    border-color: #ffffff;
-}
-
-.pagination>li>a:focus, .pagination>li>a:hover, .pagination>li>span:focus, .pagination>li>span:hover {
-    color: #343434;
-    background-color: #ffffff;
-    border-color: #ffffff;
-}
-
-/* Login
-============================================================================= */
-#login-container .card {
-  background-color: #151515;
-  color: #ffffff;
-}
-
-#login-container .login-logo {
-  background-color: rgba(255, 255, 255, 0.15);
-  border-radius: 10px;
-
-  margin: 0px auto 20px auto;
-}
-
-#login-container input,
-#login-container select,
-#login-container select option {
-  color: #ffffff;
-  background: #313131;
-}
-
-#login-container input:disabled {
-  background: #6d6d6d;
-}
-
-#login-container .btn-link {
-  color: #ffffff;
-}
-#login-container .btn-link:focus, 
-#login-container .btn-link:hover {
-  color: #b5dcff;
-}
-
-#login-container .login-btn {
-  color: #ffffff;
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6a9647), color-stop(100%,#48543d));
-  background: #464646;
-}
-
-#login-container .form-group {
-  margin-bottom: 20px;
-}
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/app.css b/client/enduser/src/main/resources/META-INF/resources/app/css/app.css
deleted file mode 100644
index 301a19b..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/css/app.css
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-/* App general css stylesheet
-============================================================================= */
-
-.growl-container > .growl-item.ng-enter,
-.growl-container > .growl-item.ng-leave {
-  -webkit-transition:1s linear all;
-  -moz-transition:1s linear all;
-  -o-transition:1s linear all;
-  transition:1s linear all;
-}
-
-.disable-link {
-  pointer-events: none;
-  cursor: default;
-}
-
-.form-control:disabled, 
-.form-control[readonly] {
-  cursor: not-allowed;
-}
-
-.card-container.card {
-  width: 350px;
-  padding: 40px 40px 0px;
-}
-
-.card {
-  background-color: #F7F7F7;
-  /* just in case there no content*/
-  padding: 20px 25px 30px;
-  margin: 0 auto 25px;
-  margin-top: 50px;
-  /* shadows and rounded borders */
-  -moz-border-radius: 2px;
-  -webkit-border-radius: 2px;
-  border-radius: 2px;
-  -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
-  -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
-  box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
-}
-
-.form-control {
-  display: block;
-  width: 100%;
-  height: 34px;
-  padding: 6px 12px;
-  font-size: 14px;
-  line-height: 1.42857;
-  color: #555;
-  background-color: #FFF;
-  /*background-image: none;*/
-  border: 1px solid #CCC;
-  border-radius: 4px;
-  box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.075) inset;
-  transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s;
-}
-
-#captchaButtons {
-  margin-top: 5%;
-  margin-bottom: 10px;
-}
-
-/* <!-- Useless with Bootstrap > 3 */
-.p-0 {
-  padding-left: 0 !important;
-  padding-right: 0 !important;
-}
-
-.float-left {
-  float: left !important;
-}
-.float-right {
-  float: right !important;
-}
-
-.btn-default {
-  color: #333;
-  background-color: #fff;
-  border-color: #ccc;
-}
-
-.pagination-size {
-  margin: 20px 0;
-  width: 20%;
-}
-
-.pagination-size-sm {
-  margin: 20px 0;
-  width: 12%;
-}
-/* Useless with Bootstrap > 3 --> */
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/customSpinner.css b/client/enduser/src/main/resources/META-INF/resources/app/css/customSpinner.css
deleted file mode 100644
index bbfe1de..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/css/customSpinner.css
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-.treasure-overlay-spinner-container{
-  z-index : 10001;
-}
-
-treasure-overlay-spinner .treasure-overlay-spinner-content {
-  height: 100%;
-}
-treasure-overlay-spinner {
-  height: 100%;
-  top: 0;
-  bottom: 0;
-  position: fixed;
-  right: 0;
-  left: 0;
-  overflow-y: auto;
-}
-
-treasure-overlay-spinner .treasure-overlay-spinner {
-  position: fixed;
-  pointer-events: none;
-}
-
-treasure-overlay-spinner .treasure-overlay-spinner-container {
-  position: fixed;
-  background: rgba(0, 0, 0, 0.5490196078431373);
-}
-
-treasure-overlay-spinner.treasure-overlay-spinner-active-remove {
-  transition: all 150ms ease-in 0s;
-}
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/editUser.css b/client/enduser/src/main/resources/META-INF/resources/app/css/editUser.css
deleted file mode 100644
index 47d64d6..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/css/editUser.css
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-/* Default style
-============================================================================= */
-* {
-  box-sizing: border-box;
-}
-
-#form-container {
-  position: relative;
-  width: 100%;
-  margin-top:-4px;
-  margin: 0 auto;
-  text-align: center;
-  background-color: #F7F7F7;
-}
-
-#form-container .breadcrumb-header {
-  margin: auto;
-  width: 80%; 
-  padding:10px; 
-}
-
-#form-container .page-header { 
-  background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%); /* FF3.6+ */
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f)); /* Chrome,Safari4+ */
-  background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Chrome10+,Safari5.1+ */
-  background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Opera 11.10+ */
-  background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* IE10+ */ 
-  margin: 1% 9%;
-  width: 83%; padding:10px; 
-  /* shadows and rounded borders */
-  -moz-border-radius: 5px;
-  -webkit-border-radius: 5px;
-  border-radius: 5px;
-  -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
-  -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
-  box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
-  text-align: left; 
-  font-weight: 700;
-}
-
-.signup-form {
-  text-align: left;
-  padding: 2%;
-}
-
-#attribute {
-  margin: auto;
-  max-width:480px;
-  padding: 10px;
-}
-
-#attribute-derived,
-#attribute-virtual {
-  padding:  155px;
-}
-
-.attribute-virtual-value-container {
-  margin-top: 2%;
-  list-style: none;
-  padding-right: 5%;
-}
-
-.attribute-virtual-value-field {
-  font-weight: 700;
-  padding: 6px 12px;
-  margin-bottom: 2%;
-}
-
-.fileButton{
-  margin-top: 2%;
-}
-
-.upper-select {
-  padding-right: 71%;
-  padding-left: 18%;
-}
-
-.attribute-ui-select {
-  width: 100%;
-  list-style: none;
-}
-
-#next,
-#previous,
-#save,
-#finish {
-  background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%);  /*FF3.6+*/ 
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f));  /*Chrome,Safari4+ */
-  background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%);  /*Chrome10+,Safari5.1+ */
-  background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%);  /*Opera 11.10+ */
-  background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%);  /*IE10+ */
-  display: inline-block;
-
-  padding-left: 8px;
-  padding-right: 8px;
-  margin-left: 5px;
-  border: none;
-  color: black;
-}
-
-#save:hover,
-#previous:hover,
-#finish:hover,
-#next:hover {
-  background: #658D5D;
-}
-
-#save {
-  margin-right: 5px;
-}
-
-#finish {
-  margin-right: 5px;
-}
-
-#cancel {
-  color: #fff;
-  margin-top: 0%;
-}
-
-.container-fluid {
-  padding-right: 15px;
-  padding-left: 15px;
-  margin-right: auto;
-  margin-left: auto;
-  width: 63%;
-}
-
-
-#form-views { width:100%; }
-
-/* basic styling for entering and leaving */
-/* left and right to add to ensure full width: position:absolute; left:30px; right:30px; */
-#form-views.ng-enter,
-#form-views.ng-leave      { 
-  position: absolute;
-  transition:0.5s all ease-in; -moz-transition:0.5s all ease-in; -webkit-transition:0.5s all ease; 
-}
-
-/* enter animation */
-#form-views.ng-enter            { 
-  -webkit-animation:slideInRight 0.5s ease;
-  -moz-animation:slideInRight 0.5s ease;
-  animation:slideInRight 0.5s ease; 
-}
-
-/* leave animation */
-#form-views.ng-leave            { 
-  position:absolute;
-  -webkit-animation:slideOutLeft 0.5s ease;
-  -moz-animation:slideOutLeft 0.5s ease;
-  animation:slideOutLeft 0.5s ease;   
-}
-
-.btn-group{
-  margin-top: 10px;
-}
-
-span.k-datetimepicker{
-  width: 170%;
-}
-
-#date, #date-property{
-  position: relative;
-  display: table; 
-  border-collapse: separate;
-  margin-bottom: -40px;
-}
-
-#timepicker{
-  line-height: 34px; 
-  float: right; 
-  padding: 0 3px 0px 0px;
-  margin-top: -65px;
-  margin-left: 39px;
-}
-
-/** Button breadcrumb **/
-.btn-breadcrumb .btn:not(:last-child):after {
-  border-left: 10px solid #ffffff;
-}
-.btn-breadcrumb .btn:not(:last-child):before {
-  margin-left: 1px;
-  border-left: 10px solid rgb(173, 173, 173);
-}
-.btn-breadcrumb .btn:not(:last-child):before,
-.btn-breadcrumb .btn:not(:last-child):after {
-  content: " ";
-  display: block;
-  width: 0;
-  height: 0;
-  border-top: 17px solid transparent;
-  border-bottom: 17px solid transparent;
-  position: absolute;
-  top: 50%;
-  margin-top: -17px;
-  left: 100%;
-  z-index: 3;
-}
-
-/** The Spacing **/
-.btn-breadcrumb .btn {
-  padding:6px 12px 6px 24px;
-}
-.btn-breadcrumb .btn:first-child {
-  padding:6px 6px 6px 10px;
-}
-.btn-breadcrumb .btn:last-child {
-  padding:6px 18px 6px 24px;
-}
-
-/** Default buttons **/
-.breadcrumb-disabled-link {
-  pointer-events: none;
-  cursor: default;
-}
-
-.breadcrumb-btn-elem {
-  border-color: #ccc;
-}
-
-.btn-breadcrumb .breadcrumb-btn-elem:not(:last-child):after {
-  border-left: 10px solid #fff;
-}
-.btn-breadcrumb .breadcrumb-btn-elem:not(:last-child):before {
-  border-left: 10px solid #ccc;
-}
-
-.btn-breadcrumb .breadcrumb-btn-elem.active:not(:last-child):after,
-.btn-breadcrumb .breadcrumb-btn-elem:hover:not(:last-child):after {
-  border-left: 10px solid #ebebeb;
-}
-.btn-breadcrumb .breadcrumb-btn-elem.active:not(:last-child):before,
-.btn-breadcrumb .breadcrumb-btn-elem:hover:not(:last-child):before {
-  border-left: 10px solid #adadad;
-}
-
-.btn-breadcrumb .breadcrumb-btn-elem.active {
-  box-shadow: 0 0px 0px rgba(0, 0, 0, 0.125)
-}
-.btn-breadcrumb .breadcrumb-btn-elem:focus {
-  box-shadow: none !important;
-}
-
-.btn-breadcrumb .btn:before,
-.btn-breadcrumb .btn:after {
-  transition: all .15s ease-in-out;
-}
-
-div[role="tablist"] {
-  margin-bottom: 20px;
-}
-
-/* For Bootstrap 4 */
-
-/*
-.btn-breadcrumb .breadcrumb-btn-elem:hover {
-  color: #ffffff !important;
-}
-
-.btn-breadcrumb .breadcrumb-btn-elem:not(:hover),
-.btn-breadcrumb .breadcrumb-home:not(:hover) {
-  color: #333;
-  background-color: #fff;
-}
-
-.btn-breadcrumb .breadcrumb-btn-elem:hover:not(:last-child):after,
-.btn-breadcrumb .breadcrumb-btn-elem:hover:not(:last-child):before,
-.btn-breadcrumb .breadcrumb-btn-elem.active:not(:last-child):after,
-.btn-breadcrumb .breadcrumb-btn-elem.active:not(:last-child):before {
-  border-left: 10px solid #4c4c4c;
-}
-*/
-
-.btn-file {
-  background: transparent;
-  color: black;
-}
-
-.text-validation-error{
-  color: #dd301b;
-  font-weight: 600;
-}
-
-.multivalue button{
-  float: right
-}
-.schema-type #date{
-  margin-top: 35px;
-  margin-bottom: 2px;
-}
-
-.schema-type #date-property {
-    margin-bottom: 2px;
-}
-
-.property-label{
-  margin-top: 15px
-}
-
-.multivalue input{
-  width: calc(100% - 70px);
-  margin-top: 10px
-}
-
-.multivalue input:disabled{
-  width: 100%;  
-}
-
-.multivalue button{
-  margin-top: 2px
-}
-
-.multivalue #datetime{
-  margin-top: 0px
-}
-
-#datetime input{
-  width: 100%;
-  margin-top: 0px
-}
-#timepicker input{
-  width: 50px;
-  margin-top: 0px
-}
-
-.multivalue #timepicker {
-  margin-top: -35px;
-}
-
-.suggestions{
-  font-size: 10px;
-  display: inline-block;
-  margin-bottom: 5px;
-}
-
-#status-buttons {
-  padding-left: 15px;
-  -webkit-flex-flow: row wrap; /* Safari 6.1+ */
-  flex-flow: row wrap;
-}
-
-.card.card-open {
-  background-color: #ffffff;
-}
-
-.card-header a {
-  text-decoration: none;
-}
-
-.card-header h5 a {
-  color: black;
-}
-
-.card-header {
-  padding: 2px 15px;
-  border-bottom: 1px solid transparent;
-  border-top-left-radius: 3px;
-  border-top-right-radius: 3px;
-  background-color: #f5f5f5;
-  border-color: #ddd;
-}
-/* end default style
-============================================================================= */
-
-/* Style for devices max width 350
-============================================================================= */
-@media only screen and (max-width: 350px) {
-
-  input[type=file] {
-    display: block;
-    color: #ffffff !important;
-  }
-
-  #form-container {
-    padding: 1px 0px 0px 0px;
-  }
-
-  .panel-body {
-    padding: 0px;
-  }
-
-  #timepicker{
-    width: 47px;
-    line-height: 34px; 
-    float: right; 
-    padding: 0 3px 0px 0px;
-    margin-top: -65px;
-  }
-
-
-  .btn-group{
-    position: relative;
-    display: inline-flex;
-    vertical-align: middle;
-    width: 90%;
-    margin-left: 35px;
-    margin-top: 10px;
-    padding: 0px 0px 1px 0px
-  }
-
-  #finish,
-  #save,
-  #next,
-  #previous {
-    padding-left: 2px;
-    padding-right: 2px;
-  }
-
-  #finish{
-    margin-left:-27px;
-    margin-top: 2px;
-  }
-  #next{
-    margin-left: 1px;
-  }
-  #previous{
-    margin-left:-126px;
-  }
-  #save{
-    margin-top: 4px;
-    margin-top:-31px;
-    margin-left: -42px;
-    margin-right: 15px;
-  }
-
-  span.k-datetimepicker {
-    width: 141%;
-    margin-top: -50px;
-  }
-
-}
-/* 
-============================================================================= */
-
-/* Style for devices max width 400
-============================================================================= */
-@media only screen and (max-width: 400px) {
-
-  input[type=file] {
-    display: block;
-  }
-
-  .panel-body {
-    padding: 0px;
-  }
-
-  #datetime input {
-    width: 100%;
-  }
-
-  #form-container {
-    padding: 1px 0px 0px 0px;
-  }
-
-  #form-container .breadcrumb-header   { 
-    margin: auto;
-    width: 100%; 
-    padding: 1px 0px 0px 0px;
-    text-align: left;
-    overflow: auto;
-  }
-
-  .btn-group{
-    position: relative;
-    display: inline-flex;
-    vertical-align: middle;
-    width: 70%;
-    margin-left: 35px;
-    margin-top: 10px;
-    padding: 0px 0px 1px 0px
-  }
-
-  .btn-breadcrumb .btn {
-    padding:6px 12px 6px 12px;
-  }
-
-  .btn-breadcrumb .btn:first-child {
-    padding:6px 6px 6px 10px;
-  }
-
-  .btn-breadcrumb .btn:last-child {
-    padding:6px 18px 6px 24px;
-  }
-
-  #next,
-  #finish,
-  #previous,
-  #save {
-    padding-left: 2px;
-  }
-
-  #finish {
-    padding-right: 2px;
-    margin-right: -3px;
-    margin-left: 0px;
-  }
-  #next {
-    padding-right: 2px;
-    margin-right: 23px;
-  }
-  #previous {
-    padding-right: 2px;
-    margin-left: 0px
-  }
-  #save {
-    padding-right: 0px;
-    margin-left: -21px;
-    margin-top: 4px;
-  }
-
-  span.k-datetimepicker{
-    width: 160%;
-  }
-
-}
-/* 
-============================================================================= */
-
-/* Style for devices max width 500
-============================================================================= */
-@media only screen and (max-width: 500px) {
-
-  * {
-    font-size:12px;
-  }
-
-  #form-container {
-    padding: 1px 0px 0px -4px;
-  }
-
-  #form-container .breadcrumb-header   { 
-    margin: auto;
-    width: 118%; 
-    text-align: left;
-    overflow: auto;
-  }
-
-  .panel-body {
-    padding: 0px;
-  }
-
-  .btn-group{
-    position: relative;
-    display: inline-flex;
-    vertical-align: middle;
-    width: 80%;
-    margin-left: 35px;
-    margin-top: 10px;
-    padding: 0px 0px 1px 0px
-  }
-
-  .btn{
-    font-size: 12px;
-  }
-
-  .btn-group .btn+.btn, 
-  .btn-group .btn+.btn-group, 
-  .btn-group .btn-group+.btn, 
-  .btn-group .btn-group+.btn-group {
-    margin-left: 0px;
-  }
-
-  .card-container.card {
-    width: 295px;
-    padding: 40px 40px 0px;
-  }
-
-  .btn-breadcrumb .btn {
-    padding:6px 12px 6px 12px;
-  }
-
-  .btn-breadcrumb .btn:first-child {
-    padding:6px 6px 6px 10px;
-  }
-
-  .btn-breadcrumb .btn:last-child {
-    padding:6px 18px 6px 24px;
-  }
-
-  #resetpassword {
-    margin-left: 5px;
-    width: 70px;
-  }
-
-  #navButtons{
-    float: right;
-    width: 75%;
-  }
-
-  .container {
-    padding-right: 0px;
-    padding-left: 0px;
-    margin-right: auto;
-    margin-left: auto;
-    /*margin-top: -4px;*/
-  }
-
-  .input-group .form-control{
-    font-size: 12px;
-  }
-
-  label {
-    font-size: 12px;
-  }
-
-  .form-control{
-    font-size: 12px;
-  }
-
-  .select2-results .select2-result-label{
-    font-size: 12px;
-  }
-
-  .select2-container-multi .select2-choices .select2-search-field input{
-    font-size:12px;
-  }
-
-  #datetime{
-    line-height: 34px;
-    float: left;
-    margin-top:-30px;
-    padding: 0 3px 0px 0px;
-    display: inline-block !important;
-    width:100px;
-  }
-
-  #date, #date-property{
-    position: relative;
-    display: table; 
-    border-collapse: separate;
-  }
-
-  #timepicker{
-    line-height: 34px; 
-    float: right; 
-    padding: 0 3px 0px 0px;
-    margin-top: -65px;
-  }
-
-  span.k-datetimepicker{
-    width: 171%;
-    margin-top: 50%;
-  }
-
-  .multivalue button{
-    width: 40px;
-  }
-
-  .row{
-    margin-left: -34px;
-    margin-right: 0px;
-    width: 100%
-  }
-
-  .navbar {
-    position: relative;
-    min-height: 50px;
-    width: 100%;
-    margin-left: 33px;
-    margin-bottom: 20px;
-    border: 1px solid transparent;
-  }
-
-  #datetime{
-    line-height: 34px;
-    float: left;
-    margin-top:-30px;
-    padding: 0 3px 0px 0px;
-    display: -webkit-inline-box;
-  }
-
-  #datetime input{
-    width: 105%;
-    margin-top: 0px
-  }
-
-  #date, #date-property{
-    position: relative;
-    display: table; 
-    border-collapse: separate;
-    margin-bottom: -40px;
-  }
-
-  #calendar{
-    position:absolute;
-    margin-top: -33px;
-    margin-left: 99px;
-    width:40px;
-  }
-
-  #timepicker{
-    line-height: 34px; 
-    float: right; 
-    padding: 0 3px 0px 0px;
-    margin-top: -64px;
-    margin-left: 48px;
-  }
-
-
-  .container-fluid {
-    padding-right: 15px;
-    padding-left: 15px;
-    margin-right: auto;
-    margin-left: 33px;
-    margin-left: 33px;
-    width: 82%;
-  }
-
-  #finish{
-    padding-left: 4px;
-    padding-right: 4px;
-    margin-top: 4px;
-    margin-right: 16px;
-  }
-  #next{
-    padding-left: 6px;
-    padding-right: 4px;
-    margin-right:-15px;
-  }
-  #previous{
-    padding-left: 4px;
-    padding-right: 4px;
-    margin-left: -87px
-  }
-  #save{
-    padding-left: 4px;
-    padding-right: 4px;
-    margin-top:4px;
-    margin-right:25px;
-
-  }
-}
-/* 
-============================================================================= */
-
-/* Style for devices max width 800)
-============================================================================= */
-@media only screen and (max-width: 800px) {
-
-  * {
-    font-size:12px;
-  }
-
-  #form-container .breadcrumb-header   { 
-    width: 97%; 
-    padding: 1px 0px 0px 0px;
-    text-align: left;
-    overflow: auto;
-  }
-
-  .panel-body {
-    padding: 0px;
-  }
-
-  .btn-group{
-    position: relative;
-    display: inline-flex;
-    vertical-align: middle;
-    width: 80%;
-    margin-left: 35px;
-    margin-top: 10px;
-    padding: 0px 0px 1px 0px
-  }
-
-  #captchaImg {
-    display: block;
-    margin: 0 auto;
-    width: 100%;
-  }
-
-}
-/* 
-============================================================================= */
-
-/* ANIMATIONS
-============================================================================= */
-/* slide out to the left */
-@keyframes slideOutLeft {
-  to      { transform: translateX(-300%); }
-}
-@-moz-keyframes slideOutLeft {  
-  to      { -moz-transform: translateX(-300%); }
-}
-@-webkit-keyframes slideOutLeft {
-  to      { -webkit-transform: translateX(-300%); }
-}
-
-/* slide in from the right */
-@keyframes slideInRight {
-  from    { transform:translateX(300%); }
-  to      { transform: translateX(0); }
-}
-@-moz-keyframes slideInRight {
-  from    { -moz-transform:translateX(300%); }
-  to      { -moz-transform: translateX(0); }
-}
-@-webkit-keyframes slideInRight {
-  from    { -webkit-transform:translateX(300%); }
-  to      { -webkit-transform: translateX(0); }
-}
-/* 
-============================================================================= */
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/init.css b/client/enduser/src/main/resources/META-INF/resources/app/css/init.css
deleted file mode 100644
index 21555b4..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/css/init.css
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-#accessibility {
-  display: none;
-}
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/login.css b/client/enduser/src/main/resources/META-INF/resources/app/css/login.css
deleted file mode 100644
index 03212f3..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/css/login.css
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-body, html {
-  background-repeat: no-repeat;
-}
-
-body{
-  margin: 0px;
-  padding:0px;
-}
-
-@media only screen and (max-width: 500px) {
-  body{
-    margin: 0px;
-    padding: 0px;
-  }
-}
-
-.login-btn {
-  background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%); /* FF3.6+ */
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f)); /* Chrome,Safari4+ */
-  background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Chrome10+,Safari5.1+ */
-  background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Opera 11.10+ */
-  background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* IE10+ */
-  margin-top: 5px;
-  color: black;
-}
-.login-btn:hover {
-  background: #658D5D;
-}
-
-#languageContainer {
-  padding: 0 25px;
-}
-
-.logout{
-  float: right;
-}
-
-.login-logo {
-  width: 200px;
-  margin: 0px auto 10px;
-  display: block;
-}
-
-.form-signin input[type=password],
-.form-signin input[type=text],
-.form-signin button {
-  width: 100%;
-  display: block;
-  margin-bottom: 10px;
-  z-index: 1;
-  position: relative;
-  -moz-box-sizing: border-box;
-  -webkit-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-input[type="number"]{
-  padding-right: 0px !important
-}
-
-.dropdown-toggle {
-  width: 100%; 
-  text-align: left;
-}
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/notification.css b/client/enduser/src/main/resources/META-INF/resources/app/css/notification.css
deleted file mode 100644
index f2d190e..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/css/notification.css
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-.k-notification-wrap {
-  white-space: normal !important;
-  word-wrap: break-word !important;
-}
-
-.k-icon {
-  margin-right: 5px;
-  vertical-align: sub;
-}
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/passwordReset.css b/client/enduser/src/main/resources/META-INF/resources/app/css/passwordReset.css
deleted file mode 100644
index 4f03f25..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/css/passwordReset.css
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-#resetpassword {
-  background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%); /* FF3.6+ */
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f)); /* Chrome,Safari4+ */
-  background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Chrome10+,Safari5.1+ */
-  background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Opera 11.10+ */
-  background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* IE10+ */
-  margin-left: 5px;
-  color: black;
-  border: none;
-}
-#resetpassword:hover {
-  background: #658D5D;
-}
-
-#captchaImg {
-  display: block;
-  margin: 0 auto;
-}
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/templates/dark/editUser.css b/client/enduser/src/main/resources/META-INF/resources/app/css/templates/dark/editUser.css
deleted file mode 100644
index dd0d351..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/css/templates/dark/editUser.css
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-html,
-body {
-  height: 100%;
-}
-body {
-  background: -moz-linear-gradient(94deg, rgba(51,51,51,1) 0%, rgba(101,141,93,1) 100%); /* ff3.6+ */
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(101,141,93,1)), color-stop(100%, rgba(51,51,51,1))); /* safari4+,chrome */
-  background: -webkit-linear-gradient(94deg, rgba(51,51,51,1) 0%, rgba(101,141,93,1) 100%); /* safari5.1+,chrome10+ */
-  background: -o-linear-gradient(94deg, rgba(51,51,51,1) 0%, rgba(101,141,93,1) 100%); /* opera 11.10+ */
-  background: -ms-linear-gradient(94deg, rgba(51,51,51,1) 0%, rgba(101,141,93,1) 100%); /* ie10+ */
-  background: linear-gradient(356deg, rgba(51,51,51,1) 0%, rgba(101,141,93,1) 100%); /* w3c */
-  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#658d5d', endColorstr='#333333',GradientType=0 ); /* ie6-9 */
-}
-
-#form-container .page-header,
-#previous,
-#next,
-#save,
-#finish,
-#resetpassword {
-  background: -moz-linear-gradient(top, #6a9647 0%, #48543d 100%); /* FF3.6+ */
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6a9647), color-stop(100%,#48543d)); /* Chrome,Safari4+ */
-  background: -webkit-linear-gradient(top, #6a9647 0%,#48543d 100%); /* Chrome10+,Safari5.1+ */
-  background: -o-linear-gradient(top, #6a9647 0%,#48543d 100%); /* Opera 11.10+ */
-  background: -ms-linear-gradient(top, #6a9647 0%,#48543d 100%); /* IE10+ */
-  color: white;
-}
-
-#form-container .btn-danger {
-  background-color: #a93f3c;
-  border-color: #ffffff;
-}
-
-
-#form-container,
-#form-container .panel {
-  background-color: #151515;
-  color: white;
-}
-
-#form-container input, 
-#form-container select,
-#form-container select option,
-#form-container label {
-  color: white;
-}
-
-#form-container input:disabled {
-  background: #6d6d6d;
-}
-
-#form-container input,
-#form-container select,
-#form-container select option,
-span.k-datepicker, 
-span.k-timepicker, 
-span.k-datetimepicker, 
-span.k-colorpicker, 
-span.k-numerictextbox, 
-span.k-combobox, 
-span.k-dropdown, 
-.k-toolbar .k-split-button,
-.k-autocomplete.k-state-default, 
-.k-picker-wrap.k-state-default, 
-.k-numeric-wrap.k-state-default, 
-.k-dropdown-wrap.k-state-default {
-  background: #313131;
-}
-
-.card-header h5 a {
-  color: white;
-}
-
-.card-header {
-  background-color: #49553e;
-}
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/templates/dark/login.css b/client/enduser/src/main/resources/META-INF/resources/app/css/templates/dark/login.css
deleted file mode 100644
index 90da4b0..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/css/templates/dark/login.css
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-html,
-body {
-  height: 100%;
-}
-body {
-  background: -moz-linear-gradient(94deg, rgba(51,51,51,1) 0%, rgba(101,141,93,1) 100%); /* ff3.6+ */
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(101,141,93,1)), color-stop(100%, rgba(51,51,51,1))); /* safari4+,chrome */
-  background: -webkit-linear-gradient(94deg, rgba(51,51,51,1) 0%, rgba(101,141,93,1) 100%); /* safari5.1+,chrome10+ */
-  background: -o-linear-gradient(94deg, rgba(51,51,51,1) 0%, rgba(101,141,93,1) 100%); /* opera 11.10+ */
-  background: -ms-linear-gradient(94deg, rgba(51,51,51,1) 0%, rgba(101,141,93,1) 100%); /* ie10+ */
-  background: linear-gradient(356deg, rgba(51,51,51,1) 0%, rgba(101,141,93,1) 100%); /* w3c */
-  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#658d5d', endColorstr='#333333',GradientType=0 ); /* ie6-9 */
-}
-
-#login-container .card {
-  background-color: #151515;
-  color: white;
-}
-
-#login-container .login-logo {
-  background-color: rgba(255, 255, 255, 0.15);
-  border-radius: 10px;
-
-  margin: 0px auto 20px auto;
-}
-
-#login-container input,
-#login-container select,
-#login-container select option {
-  color: white;
-  background: #313131;
-}
-
-#login-container input:disabled {
-  background: #6d6d6d;
-}
-
-#login-container .btn-link {
-  color: #82b9e8;
-}
-#login-container .btn-link:focus, 
-#login-container .btn-link:hover {
-  color: #b5dcff;
-}
-
-#login-container .login-btn {
-  color: white;
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6a9647), color-stop(100%,#48543d));
-
-  background: linear-gradient(top, #6a9647 0%,#48543d 100%);
-  background: -webkit-linear-gradient(top, #6a9647 0%,#48543d 100%);
-  background: -moz-linear-gradient(top, #6a9647 0%, #48543d 100%);
-  background: -o-linear-gradient(top, #6a9647 0%,#48543d 100%);
-  background: -ms-linear-gradient(top, #6a9647 0%,#48543d 100%);
-}
-
-#login-container .form-group {
-  margin-bottom: 20px;
-}
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/img/ajax-loader.gif b/client/enduser/src/main/resources/META-INF/resources/app/img/ajax-loader.gif
deleted file mode 100644
index 766cf24..0000000
Binary files a/client/enduser/src/main/resources/META-INF/resources/app/img/ajax-loader.gif and /dev/null differ
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/img/busy.gif b/client/enduser/src/main/resources/META-INF/resources/app/img/busy.gif
deleted file mode 100644
index e77264f..0000000
Binary files a/client/enduser/src/main/resources/META-INF/resources/app/img/busy.gif and /dev/null differ
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/img/favicon.png b/client/enduser/src/main/resources/META-INF/resources/app/img/favicon.png
deleted file mode 100644
index aa2f3e2..0000000
Binary files a/client/enduser/src/main/resources/META-INF/resources/app/img/favicon.png and /dev/null differ
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/img/logo-green.png b/client/enduser/src/main/resources/META-INF/resources/app/img/logo-green.png
deleted file mode 100644
index c57b86c..0000000
Binary files a/client/enduser/src/main/resources/META-INF/resources/app/img/logo-green.png and /dev/null differ
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/img/logo.png b/client/enduser/src/main/resources/META-INF/resources/app/img/logo.png
deleted file mode 100644
index f05105e..0000000
Binary files a/client/enduser/src/main/resources/META-INF/resources/app/img/logo.png and /dev/null differ
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/index.html b/client/enduser/src/main/resources/META-INF/resources/app/index.html
deleted file mode 100644
index 7122b50..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/index.html
+++ /dev/null
@@ -1,171 +0,0 @@
-<!DOCTYPE html>
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-<!--[if lt IE 7]>      <html lang="en" ng-app="myApp" class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
-<!--[if IE 7]>         <html lang="en" ng-app="myApp" class="no-js lt-ie9 lt-ie8"> <![endif]-->
-<!--[if IE 8]>         <html lang="en" ng-app="myApp" class="no-js lt-ie9"> <![endif]-->
-<!--[if gt IE 8]><!--> <html lang="en" ng-app="SyncopeEnduserApp" class="no-js"> <!--<![endif]-->
-  <head>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-    <meta charset="UTF-8"/>
-    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
-    <meta name="description" content=""/>
-    <meta name="viewport" content="width=device-width, initial-scale=1"/>
-
-    <title>Apache Syncope - EndUser</title>
-
-    <link rel="shortcut icon" href="img/favicon.png" type="image/png"/>
-
-    <link href="../webjars/jquery-ui/${jquery-ui.version}/jquery-ui.css" rel="stylesheet" type="text/css"/>
-    <link href="../webjars/bootstrap/${bootstrap.version}/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
-    <link href="../webjars/bootstrap-select/${bootstrap-select.version}/css/bootstrap-select.min.css" rel="stylesheet" type="text/css"/>
-    <link href="../webjars/font-awesome/${font-awesome.version}/css/${font-awesome.filename}" rel="stylesheet" type="text/css"/>
-    <link href="../webjars/ionicons/${ionicons.version}/css/ionicons.min.css" rel="stylesheet" type="text/css"/>
-    <link href="../webjars/angular-ui-select/${angular-ui-select.version}/select.css" rel="stylesheet" type="text/css"/>
-    <link href="../webjars//kendo-ui-core/${kendo-ui-core.version}/styles/web/kendo.common.core.min.css" rel="stylesheet" type="text/css"/>
-    <link href="../webjars//kendo-ui-core/${kendo-ui-core.version}/styles/web/kendo.default.min.css" rel="stylesheet" type="text/css"/>
-    <link href="../webjars/angular-treasure-overlay-spinner/${angular-treasure-overlay-spinner.version}/dist/treasure-overlay-spinner.min.css" rel="stylesheet" type="text/css"/>
-    <link href="../webjars/ng-password-strength/${ng-password-strength.version}/dist/styles/main.css" rel="stylesheet" type="text/css">
-    <link href="../webjars/select2/${select2.version}/select2.css" rel="stylesheet"/>
-
-    <link href="css/init.css" rel="stylesheet" type="text/css"/>
-    <link href="css/customSpinner.css" rel="stylesheet" type="text/css"/>
-  </head>
-  <body ng-cloak >
-
-  <!--[if lt IE 7]>
-      <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
-  <![endif]-->
-
-  <span id="notifications"></span>
-
-  <treasure-overlay-spinner active='spinner.active'>
-    <div ng-cloak ng-controller="ApplicationController" ng-init="initApplication()">   
-      <div id="accessibility" ng-controller="AccessibilityController">
-        <div id="change_contrast" class="btn-accessibility" 
-             ng-init="checkPref(HC_THEME_PREF)">
-          <i ng-click="switchTheme()"
-             aria-label="Toggle high contrast colors mode" tabindex="0" accesskey="H"
-             class="fa fa-adjust">
-          </i>
-        </div>
-        <div id="change_fontSize" class="btn-accessibility" 
-             ng-init="checkPref(FONT_SIZE_PREF)">
-          <i ng-click="switchIncreasedFont()"
-             aria-label="Toggle font size increment" tabindex="0" accesskey="F"
-             class="fa fa-font">
-          </i>
-        </div>
-      </div>
-
-      <!-- Dynamic view -->
-      <div ui-view></div>
-    </div>
-  </treasure-overlay-spinner>
-
-  <script src="../webjars/jquery/${jquery.version}/jquery.js"></script>
-  <script src="../webjars/angular/${angular.version}/angular.js"></script>
-  <script src="../webjars/angular-ui-router/${angular-ui-router.version}/release/angular-ui-router.js"></script>
-  <script src="../webjars/angular-animate/${angular.version}/angular-animate.js"></script>
-  <script src="../webjars/angular-resource/${angular-resource.version}/angular-resource.js"></script>
-  <script src="../webjars/angular-cookies/${angular.version}/angular-cookies.js"></script>
-  <script src="../webjars/angular-sanitize/${angular.version}/angular-sanitize.js"></script>
-  <script src="../webjars/ui-bootstrap4/${ui-bootstrap.version}/dist/ui-bootstrap.js"></script>
-  <script src="../webjars/ui-bootstrap4/${ui-bootstrap.version}/dist/ui-bootstrap-tpls.js"></script>
-  <script src="../webjars/angular-ui-select/${angular-ui-select.version}/select.js"></script>
-  <script src="../webjars/kendo-ui-core/${kendo-ui-core.version}/js/kendo.ui.core.min.js"></script>
-  <script src="../webjars/kendo-ui-core/${kendo-ui-core.version}/js/kendo.notification.min.js"></script>
-  <script src="../webjars/kendo-ui-core/${kendo-ui-core.version}/js/kendo.angular.js"></script>
-  <script src="../webjars/kendo-ui-core/${kendo-ui-core.version}/js/cultures/kendo.culture.it.js"></script>
-  <script src="../webjars/kendo-ui-core/${kendo-ui-core.version}/js/cultures/kendo.culture.en.js"></script>
-  <script src="../webjars/kendo-ui-core/${kendo-ui-core.version}/js/cultures/kendo.culture.de.js"></script>
-  <script src="../webjars/kendo-ui-core/${kendo-ui-core.version}/js/cultures/kendo.culture.ja.js"></script>
-  <script src="../webjars/angular-treasure-overlay-spinner/${angular-treasure-overlay-spinner.version}/dist/treasure-overlay-spinner.min.js"></script>
-  <script src="../webjars/ng-password-strength/${ng-password-strength.version}/dist/scripts/ng-password-strength.min.js"></script>
-  <script src="../webjars/bootstrap-select/${bootstrap-select.version}/js/bootstrap-select.min.js"></script>
-  <script src="../webjars/FileSaver.js/${fileSaver.version}/FileSaver.js"></script>
-  <script src="../webjars/lodash/${lodash.version}/lodash.min.js"></script>
-  <script src="../webjars/angular-translate/${angular-translate.version}/angular-translate.js"></script>
-  <script src="../webjars/angular-translate-loader-partial/${angular-translate-loader-partial.version}/angular-translate-loader-partial.js"></script>
-  <script src="../webjars/angular-translate-storage-cookie/${angular-translate.version}/angular-translate-storage-cookie.js"></script>
-  <script src="../webjars/bootstrap-fileinput/${bootstrap-fileinput.version}/js/fileinput.js"></script>
-  <script src="../webjars/angular-aria/${angular.version}/angular-aria.min.js" ></script>
-
-  <!--main angular application-->
-  <script src="js/app.js"></script>
-  <!--services-->
-  <script src="js/services/authService.js"></script>
-  <script src="js/services/userSelfService.js"></script>
-  <script src="js/services/schemaService.js"></script>
-  <script src="js/services/realmService.js"></script>
-  <script src="js/services/securityQuestionService.js"></script>
-  <script src="js/services/infoService.js"></script>
-  <script src="js/services/dynamicTemplateService.js"></script>
-  <script src="js/services/resourceService.js"></script>
-  <script src="js/services/groupService.js"></script>
-  <script src="js/services/anyService.js"></script>
-  <script src="js/services/saml2IdPService.js"></script>
-  <script src="js/services/oidcProviderService.js"></script>
-  <script src="js/services/saml2SPService.js"></script>
-  <script src="js/services/oidcClientService.js"></script>
-  <script src="js/services/bpmnProcessService.js"></script>
-  <script src="js/services/userRequestsService.js"></script>
-  <!--controllers-->
-  <script src="js/controllers/HomeController.js"></script>
-  <script src="js/controllers/LoginController.js"></script>
-  <script src="js/controllers/SAML2SPController.js"></script>
-  <script src="js/controllers/OIDCClientController.js"></script>
-  <script src="js/controllers/UserController.js"></script>
-  <script src="js/controllers/AccessibilityController.js"></script>
-  <!--directives-->
-  <script src="js/directives/dynamicPlainAttribute.js"></script>
-  <script src="js/directives/dynamicDerivedAttribute.js"></script>
-  <script src="js/directives/dynamicVirtualAttribute.js"></script>
-  <script src="js/directives/dynamicPlainAttributes.js"></script>
-  <script src="js/directives/dynamicDerivedAttributes.js"></script>
-  <script src="js/directives/dynamicVirtualAttributes.js"></script>
-  <script src="js/directives/navigationButtonsPartial.js"></script>
-  <script src="js/directives/loader.js"></script>
-  <script src="js/directives/captcha.js"></script>
-  <script src="js/directives/resources.js"></script>
-  <script src="js/directives/requests.js"></script>
-  <script src="js/directives/requestForms.js"></script>
-  <script src="js/directives/formProperty.js"></script>
-  <script src="js/directives/groups.js"></script>
-  <script src="js/directives/auxClasses.js"></script>
-  <script src="js/directives/validate.js"></script>
-  <script src="js/directives/validationMessage.js"></script>
-  <script src="js/directives/validateDropdown.js"></script>
-  <script src="js/directives/fileInput.js"></script>
-  <script src="js/directives/dynamicTemplateItem.js"></script>
-  <script src="js/directives/modalWindow.js"></script>
-  <script src="js/directives/bpmnProcesses.js"></script>
-  <script src="js/directives/modalContent.js"></script>
-  <script src="js/directives/ngEnter.js"></script>
-  <!--validator-->
-  <script src="js/validator/validationRules.js"></script>
-  <script src="js/validator/validationExecutor.js"></script>
-  <!--filters-->
-  <script src="js/filters/propsFilter.js"></script>
-  <!--util-->
-  <script src="js/util/userUtil.js"></script>
-  <script src="js/util/genericUtil.js"></script>
-  <script src="js/util/assetsManager.js"></script>
-</body>
-</html>
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/app.js b/client/enduser/src/main/resources/META-INF/resources/app/js/app.js
deleted file mode 100644
index f95093e..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/app.js
+++ /dev/null
@@ -1,730 +0,0 @@
-/**
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
- **/
-
-'use strict';
-angular.module('home', []);
-angular.module('login', []);
-angular.module('language', []);
-angular.module('self', []);
-angular.module('info', []);
-/*
- * AngularJS application modules from which depend views and components
- */
-var app = angular.module('SyncopeEnduserApp', [
-  'ui.router',
-  'ui.bootstrap',
-  'ui.select',
-  'ngSanitize',
-  'ngAnimate',
-  'ngResource',
-  'treasure-overlay-spinner',
-  'ngPasswordStrength',
-  'kendo.directives',
-  'home',
-  'login',
-  'language',
-  'self',
-  'info',
-  'ngCookies',
-  'pascalprecht.translate',
-  'ngAria'
-]);
-
-app.config(['$stateProvider', '$urlRouterProvider', '$httpProvider', '$translateProvider', '$translatePartialLoaderProvider',
-  function ($stateProvider, $urlRouterProvider, $httpProvider, $translateProvider, $translatePartialLoaderProvider) {
-    /*
-     |--------------------------------------------------------------------------
-     | Syncope Enduser AngularJS providers configuration
-     |--------------------------------------------------------------------------
-     */
-
-    /*
-     * i18n provider
-     */
-    $translatePartialLoaderProvider.addPart('static');
-    $translateProvider.useLoader('$translatePartialLoader', {
-      urlTemplate: 'languages/{lang}/{part}.json'
-    }).preferredLanguage('en');
-    /*
-     * State provider
-     */
-    $stateProvider
-            .state('home', {
-              url: '/',
-              templateUrl: 'views/self.html',
-              resolve: {
-                loadAssets: ['DynamicTemplateService', function (DynamicTemplateService) {
-                    return DynamicTemplateService.getGeneralAssetsContent(["css"]);
-                  }]
-              }
-            })
-            .state('self', {
-              url: '/self?errorMessage',
-              templateUrl: 'views/self.html'
-            })
-
-            /* <Extensions> */
-            .state('self-saml2sp', {
-              url: '/self-saml2sp',
-              templateUrl: 'views/self.html',
-              controller: 'SAML2SPController',
-              resolve: {
-                'userAttrs': ['SAML2SPService',
-                  function (SAML2SPService) {
-                    return SAML2SPService.getSAML2SPUserAttrs();
-                  }]
-              }
-            })
-            /* </Extensions> */
-
-            /* <Extensions> */
-            .state('self-oidcclient', {
-              url: '/self-oidcclient',
-              templateUrl: 'views/self.html',
-              controller: 'OIDCClientController',
-              resolve: {
-                'userAttrs': ['OIDCClientService',
-                  function (OIDCClientService) {
-                    return OIDCClientService.getOIDCClientUserAttrs();
-                  }]
-              }
-            })
-            /* </Extensions> */
-
-            .state('user-self-update', {
-              url: '/user-self-update',
-              templateUrl: 'views/home.html',
-              controller: 'HomeController',
-              resolve: {
-                'authenticated': ['AuthService',
-                  function (AuthService) {
-                    return AuthService.islogged();
-                  }]
-              }
-            })
-            .state('create', {
-              url: '/self/create',
-              templateUrl: 'views/editUser.html'
-            })
-            // nested states 
-            // each of these sections will have their own view
-            // url will be nested (/self/create)
-            .state('create.credentials', {
-              url: '/credentials',
-              templateUrl: 'views/user-credentials.html'
-            })
-            .state('create.groups', {
-              url: '/groups',
-              templateUrl: 'views/user-groups.html'
-            })
-            .state('create.plainSchemas', {
-              url: '/plainSchemas',
-              templateUrl: 'views/user-plain-schemas.html'
-            })
-            .state('create.derivedSchemas', {
-              url: '/derivedSchemas',
-              templateUrl: 'views/user-derived-schemas.html'
-            })
-            .state('create.virtualSchemas', {
-              url: '/virtualSchemas',
-              templateUrl: 'views/user-virtual-schemas.html'
-            })
-            .state('create.resources', {
-              url: '/resources',
-              templateUrl: 'views/user-resources.html'
-            })
-            .state('create.finish', {
-              url: '/finish',
-              templateUrl: 'views/user-form-finish.html'
-            })
-            .state('update', {
-              url: '/self/update',
-              templateUrl: 'views/editUser.html',
-              resolve: {
-                'authenticated': ['AuthService',
-                  function (AuthService) {
-                    return AuthService.islogged();
-                  }]
-              }
-            })
-            // nested states 
-            // each of these sections will have their own view
-            // url will be nested (/self/update)
-            .state('update.credentials', {
-              url: '/credentials',
-              templateUrl: 'views/user-credentials.html',
-              resolve: {
-                'authenticated': ['AuthService',
-                  function (AuthService) {
-                    return AuthService.islogged();
-                  }]
-              }
-            })
-            .state('update.plainSchemas', {
-              url: '/plainSchemas',
-              templateUrl: 'views/user-plain-schemas.html',
-              resolve: {
-                'authenticated': ['AuthService',
-                  function (AuthService) {
-                    return AuthService.islogged();
-                  }]
-              }
-            })
-            .state('update.derivedSchemas', {
-              url: '/derivedSchemas',
-              templateUrl: 'views/user-derived-schemas.html',
-              resolve: {
-                'authenticated': ['AuthService',
-                  function (AuthService) {
-                    return AuthService.islogged();
-                  }]
-              }
-            })
-            .state('update.virtualSchemas', {
-              url: '/virtualSchemas',
-              templateUrl: 'views/user-virtual-schemas.html',
-              resolve: {
-                'authenticated': ['AuthService',
-                  function (AuthService) {
-                    return AuthService.islogged();
-                  }]
-              }
-            })
-            .state('update.groups', {
-              url: '/groups',
-              templateUrl: 'views/user-groups.html',
-              resolve: {
-                'authenticated': ['AuthService',
-                  function (AuthService) {
-                    return AuthService.islogged();
-                  }]
-              }
-            })
-            .state('update.resources', {
-              url: '/resources',
-              templateUrl: 'views/user-resources.html',
-              resolve: {
-                'authenticated': ['AuthService',
-                  function (AuthService) {
-                    return AuthService.islogged();
-                  }]
-              }
-            })
-            /* <Extensions> */
-            .state('update.userRequests', {
-              url: '/user-requests',
-              templateUrl: 'views/user-requests.html',
-              resolve: {
-                'authenticated': ['AuthService',
-                  function (AuthService) {
-                    return AuthService.islogged();
-                  }]
-              }
-            })
-            .state('update.userRequestForms', {
-              url: '/user-request-forms',
-              templateUrl: 'views/user-request-forms.html',
-              resolve: {
-                'authenticated': ['AuthService',
-                  function (AuthService) {
-                    return AuthService.islogged();
-                  }]
-              }
-            })
-            /* </Extensions> */
-            .state('update.finish', {
-              url: '/finish',
-              templateUrl: 'views/user-form-finish.html',
-              resolve: {
-                'authenticated': ['AuthService',
-                  function (AuthService) {
-                    return AuthService.islogged();
-                  }]
-              }
-            })
-            .state('passwordreset', {
-              url: '/passwordreset',
-              templateUrl: 'views/passwordreset.html'
-            })
-            .state('confirmpasswordreset', {
-              url: '/confirmpasswordreset?token',
-              templateUrl: 'views/confirmpasswordreset.html'
-            })
-            .state('mustchangepassword', {
-              url: '/mustchangepassword',
-              templateUrl: 'views/mustchangepassword.html'
-            });
-    /*
-     * catch all other routes and send users to the home page 
-     */
-    $urlRouterProvider.otherwise('/');
-    /*
-     * HTTP provider
-     */
-    $httpProvider.defaults.withCredentials = true;
-    $httpProvider.defaults.xsrfCookieName = 'XSRF-TOKEN';
-    $httpProvider.defaults.xsrfHeaderName = 'X-XSRF-TOKEN';
-    /*
-     * SYNCOPE-780
-     */
-    $httpProvider.defaults.headers.common["If-Modified-Since"] = "0";
-    $httpProvider.interceptors.push(function ($q, $rootScope) {
-      return {
-        'request': function (config, a, b) {
-          //if the url is an html, we're changing page
-          if (config.url.indexOf('.html', config.url.length - 5) === -1) {
-            $rootScope.$broadcast("xhrStarted");
-            var separator = config.url.indexOf('?') === -1 ? '?' : '&';
-            config.url = config.url + separator + 'noCache=' + new Date().getTime();
-          }
-          $rootScope.spinner.on();
-          return config || $q.when(config);
-        },
-        'response': function (response) {
-          $rootScope.spinner.off();
-          return response || $q.when(response);
-        },
-        'responseError': function (response) {
-          $rootScope.spinner.off();
-          if (response.config && response.config.url.indexOf("acceptError=true") === -1) {
-            var status = response.status;
-            if (status === 401) {
-              console.error("ERROR ", status);
-            }
-            if (status === 403) {
-              console.error("UNAUTHORIZED ", status);
-            }
-            if (status === 400 || status === 404 || status === 412 || status === 500) {
-              console.error("GENERIC ERROR ", status);
-            }
-          }
-          return $q.reject(response);
-        }
-      };
-    });
-  }]);
-app.run(['$rootScope', '$state', 'AuthService', '$transitions',
-  function ($rootScope, $state, AuthService, $transitions) {
-    /*
-     |--------------------------------------------------------------------------
-     | Main of Syncope Enduser application
-     |
-     | keep user logged in after page refresh
-     | If the route change failed due to authentication error, redirect them out
-     |--------------------------------------------------------------------------
-     */
-    $transitions.onError({}, function (trans) {
-      if (trans.error().message === 'Not Authenticated') {
-        $state.go('home');
-      }
-    });
-
-    $transitions.onSuccess({}, function (trans) {
-      var toState = trans.$to();
-      var fromState = trans.$from();
-
-      if (toState.name === 'create') {
-        $state.go('create' + $rootScope.getWizardFirstStep());
-      } else if (toState.name === 'update') {
-        $state.go('update' + $rootScope.getWizardFirstStep());
-      } else if (toState.name.indexOf("update") > -1) {
-        AuthService.islogged().then(function (response) {
-          if (response === "true") {
-            $state.go(toState);
-          } else {
-            $state.go('home');
-          }
-        }, function (response) {
-          console.error("Not logged");
-          $state.go('home');
-        }
-        );
-      } else if (toState.name === 'home' || toState.name === 'self') {
-        if (fromState.name === 'home' || fromState.name === 'self') {
-          return false;
-        }
-
-        AuthService.islogged().then(function (response) {
-          if (response === "true") {
-            $state.go('update' + $rootScope.getWizardFirstStep());
-          }
-        }, function (response) {
-          console.error("not logged");
-          $state.go('home');
-        });
-        /*
-         * enable "finish" button on every page in create mode
-         */
-      } else if (toState.name === 'create.finish') {
-        if (fromState.name === 'create.finish') {
-          return false;
-        }
-
-        $rootScope.endReached = true;
-      } else {
-        if (fromState.name === toState.name) {
-          return false;
-        }
-
-        $state.go(toState);
-      }
-    });
-
-    $rootScope.spinner = {
-      active: false,
-      on: function () {
-        this.active = true;
-      },
-      off: function () {
-        this.active = false;
-      }
-    };
-  }]);
-app.controller('ApplicationController', ['$scope', '$rootScope', 'InfoService', 'SAML2IdPService',
-  'OIDCProviderService', 'DynamicTemplateService',
-  function ($scope, $rootScope, InfoService, SAML2IdPService, OIDCProviderService, DynamicTemplateService) {
-    $scope.initApplication = function () {
-      /* 
-       * disable by default wizard buttons in self-registration
-       */
-      $rootScope.endReached = false;
-      /*
-       |--------------------------------------------------------------------------
-       | Syncope Enduser i18n initialization
-       |--------------------------------------------------------------------------
-       */
-      $rootScope.languages = {
-        availableLanguages: [
-          {id: '1', name: 'Italiano', code: 'it', format: 'dd/MM/yyyy HH:mm'},
-          {id: '2', name: 'English', code: 'en', format: 'MM/dd/yyyy HH:mm'},
-          {id: '3', name: 'Deutsch', code: 'de', format: 'dd/MM/yyyy HH:mm'},
-          {id: '4', name: '日本語', code: 'ja', format: 'yyyy/MM/dd HH:mm'}
-        ]
-      };
-      $rootScope.languages.selectedLanguage = $rootScope.languages.availableLanguages[1];
-      /*
-       |--------------------------------------------------------------------------
-       | Syncope Enduser properties initialization
-       | get info from InfoService API (info settings are initialized every time an user reloads the login page)
-       |--------------------------------------------------------------------------
-       */
-      $rootScope.selfRegAllowed = false;
-      $rootScope.pwdResetAllowed = false;
-      $rootScope.version = "";
-      $rootScope.pwdResetRequiringSecurityQuestions = false;
-      $rootScope.captchaEnabled = false;
-      $rootScope.validationEnabled = true;
-      $rootScope.saml2idps = {
-        available: [],
-        selected: {}
-      };
-      $rootScope.oidcops = {
-        available: [],
-        selected: {}
-      };
-
-      var doGetDynamicTemplateJSON = function (callback) {
-        if (!$rootScope.dynTemplate) {
-          DynamicTemplateService.getContent().then(
-                  function (response) {
-                    /* 
-                     * USER dynamic template JSON
-                     */
-                    $rootScope.dynTemplate = response;
-
-                    /*
-                     * Wizard steps from JSON, if some extensions are enabled add steps dynamically
-                     */
-                    $scope.wizard = response.wizard.steps;
-                    $scope.creationWizard = $scope.clone($scope.wizard);
-                    /* <Extensions> */
-                    $scope.wizard.userRequests = {
-                      "url": "/user-requests"
-                    };
-                    $scope.wizard.userRequestForms = {
-                      "url": "/user-request-forms"
-                    };
-                    /* </Extensions> */
-                    $scope.wizardFirstStep = response.wizard.firstStep;
-
-                    callback($rootScope.dynTemplate);
-                  },
-                  function (response) {
-                    console.error("Something went wrong while accessing dynamic template resource", response);
-                  });
-        } else {
-          callback($rootScope.dynTemplate);
-        }
-      };
-      $rootScope.getDynamicTemplateInfo = function (type, key, callback) {
-        if (type) {
-          doGetDynamicTemplateJSON(function (templateJSON) {
-            callback((templateJSON && templateJSON["templates"] && templateJSON["templates"][type])
-                    ? templateJSON["templates"][type][key]
-                    : "");
-          });
-        } else {
-          callback("");
-        }
-      };
-      $rootScope.getDynamicTemplateOtherInfo = function (type, key, callback) {
-        if (type) {
-          doGetDynamicTemplateJSON(function (templateJSON) {
-            callback((templateJSON && templateJSON[type])
-                    ? templateJSON[type][key]
-                    : "");
-          });
-        } else {
-          callback("");
-        }
-      };
-
-      $rootScope.getWizardFirstStep = function () {
-        return $scope.wizardFirstStep ? ('.' + $scope.wizardFirstStep) : '';
-      };
-
-      InfoService.getInfo().then(
-              function (response) {
-                $rootScope.pwdResetAllowed = response.pwdResetAllowed;
-                $rootScope.selfRegAllowed = response.selfRegAllowed;
-                $rootScope.version = response.version;
-                $rootScope.pwdResetRequiringSecurityQuestions = response.pwdResetRequiringSecurityQuestions;
-                $rootScope.captchaEnabled = response.captchaEnabled;
-                $rootScope.maxUploadFileSizeMB = response.maxUploadFileSizeMB;
-                /* 
-                 * USER form customization JSON
-                 */
-                $rootScope.customFormAttributes = response.customFormAttributes;
-              },
-              function (response) {
-                console.error("Something went wrong while accessing info resource", response);
-              });
-
-      /* <Extensions> */
-      SAML2IdPService.getAvailableSAML2IdPs().then(
-              function (response) {
-                $rootScope.saml2idps.available = response;
-              },
-              function (response) {
-                console.debug("No SAML 2.0 SP extension available", response);
-              });
-      /* </Extensions> */
-      /* <Extensions> */
-      OIDCProviderService.getAvailableOIDCProviders().then(
-              function (response) {
-                $rootScope.oidcops.available = response;
-              },
-              function (response) {
-                console.debug("No OIDC Client extension available", response);
-              });
-      /* </Extensions> */
-
-      /* 
-       * configuration getters
-       */
-      $rootScope.isSelfRegAllowed = function () {
-        return $rootScope.selfRegAllowed === true;
-      };
-      $rootScope.isPwdResetAllowed = function () {
-        return $rootScope.pwdResetAllowed === true;
-      };
-      $rootScope.saml2spExtAvailable = function () {
-        return $rootScope.saml2idps.available.length > 0;
-      };
-      $rootScope.saml2login = function () {
-        window.location.href = '../saml2sp/login?idp=' + $rootScope.saml2idps.selected.entityID;
-      };
-
-      $rootScope.oidcclientExtAvailable = function () {
-        return $rootScope.oidcops.available.length > 0;
-      };
-      $rootScope.oidclogin = function () {
-        window.location.href = '../oidcclient/login?op=' + $rootScope.oidcops.selected.name;
-      };
-      $rootScope.getVersion = function () {
-        return $rootScope.version;
-      };
-      $rootScope.getMaxUploadFileSizeMB = function () {
-        return $rootScope.maxUploadFileSizeMB;
-      };
-
-      /* 
-       * USER Attributes sorting strategies
-       */
-      $rootScope.attributesSorting = {
-        ASC: function (a, b) {
-          var schemaNameA = a.key;
-          var schemaNameB = b.key;
-          return schemaNameA < schemaNameB ? -1 : schemaNameA > schemaNameB ? 1 : 0;
-        },
-        DESC: function (a, b) {
-          var schemaNameA = a.key;
-          var schemaNameB = b.key;
-          return schemaNameA < schemaNameB ? 1 : schemaNameA > schemaNameB ? -1 : 0;
-        }
-      };
-
-      /* 
-       * Date formatters
-       */
-
-      // from timestamp
-      $rootScope.formatDate = function (timestamp) {
-        return new Date(timestamp).toLocaleString();
-      };
-
-      /*
-       |--------------------------------------------------------------------------
-       | Notification mgmt
-       |--------------------------------------------------------------------------
-       */
-      $scope.notificationSuccessTimeout = 4000;
-//      $scope.notification = $('#notifications').kendoNotification().data("kendoNotification");
-      $scope.notification = $("#notifications").kendoNotification({
-        stacking: "down",
-        hideOnClick: true,
-        width: 320
-      }).data("kendoNotification");
-      $scope.notification.options.position["top"] = 20;
-      $scope.showSuccess = function (message, component) {
-        if (!$scope.notificationExists(message)) {
-          //forcing scrollTo since kendo doesn't disable scrollTop if pinned is true
-          window.scrollTo(0, 0);
-          component.options.autoHideAfter = $scope.notificationSuccessTimeout;
-          component.show(message, "success");
-        }
-      };
-      $scope.showError = function (message, component) {
-        if (!$scope.notificationExists(message)) {
-          //forcing scrollTo since kendo doesn't disable scrollTop if pinned is true
-          window.scrollTo(0, 0);
-          component.options.autoHideAfter = 0;
-          component.show(message, "error");
-        }
-      };
-      $scope.hideError = function (message, component) {
-        var popup;
-        if (popup = $scope.notificationExists(message)) {
-          popup.hide = true;
-          popup.close();
-        }
-      };
-      $scope.notificationExists = function (message) {
-        var result = false;
-        if ($scope.notification) {
-          var pendingNotifications = $scope.notification.getNotifications();
-          pendingNotifications.each(function (idx, element) {
-            var popup = $(element).data("kendoPopup");
-            if (!popup.hide && popup.wrapper.html().indexOf(message) > -1) {
-              result = popup;
-              return false; //breaking the each and storing the real result
-            }
-          });
-        }
-        return result;
-      };
-      $scope.hideNotifications = function (timer) {
-        if ($scope.notification) {
-          var pendingNotifications = $scope.notification.getNotifications();
-          if (timer && timer > 0) {
-            setTimeout(function () {
-              pendingNotifications.each(function (idx, element) {
-                var popup = $(element).data("kendoPopup");
-                if (popup) {
-                  popup.hide = true;
-                  popup.close();
-                }
-              });
-            }, timer);
-          } else {
-            pendingNotifications.each(function (idx, element) {
-              var popup = $(element).data("kendoPopup");
-              if (popup) {
-                popup.hide = true;
-                //we should destroy the message immediately
-                popup.destroy();
-              }
-            });
-          }
-        }
-      };
-
-      /*
-       * Intercepting location change event
-       * When a location changes, old notifications should be removed
-       */
-      $rootScope.$on("$locationChangeStart", function (event, next, current) {
-        $scope.hideNotifications($scope.notificationSuccessTimeout);
-      });
-      //Intercepting xhr start event
-      $scope.$on('xhrStarted', function (event, next, current) {
-        $scope.hideNotifications(0);
-      });
-      //Intercepting hide popup errors event
-      $scope.$on('hideErrorMessage', function (event, popupMessage) {
-        $scope.hideError(popupMessage, $scope.notification);
-      });
-
-      /*
-       |--------------------------------------------------------------------------
-       | Utilities
-       |--------------------------------------------------------------------------
-       */
-      $scope.clearCache = function () {
-        $templateCache.removeAll();
-      };
-    };
-
-    $scope.clone = function clone(obj) {
-      var copy;
-
-      // Handle the 3 simple types, and null or undefined
-      if (null == obj || "object" != typeof obj)
-        return obj;
-
-      // Handle Date
-      if (obj instanceof Date) {
-        copy = new Date();
-        copy.setTime(obj.getTime());
-        return copy;
-      }
-
-      // Handle Array
-      if (obj instanceof Array) {
-        copy = [];
-        for (var i = 0, len = obj.length; i < len; i++) {
-          copy[i] = clone(obj[i]);
-        }
-        return copy;
-      }
-
-      // Handle Object
-      if (obj instanceof Object) {
-        copy = {};
-        for (var attr in obj) {
-          if (obj.hasOwnProperty(attr))
-            copy[attr] = clone(obj[attr]);
-        }
-        return copy;
-      }
-
-      throw new Error("Unable to copy obj! Its type isn't supported.");
-    };
-
-  }]);
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/AccessibilityController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/AccessibilityController.js
deleted file mode 100644
index 1d9e799..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/AccessibilityController.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
- **/
-
-'use strict';
-angular.module("home").controller("AccessibilityController", ['$scope', 'AssetsManager', '$window',
-  function ($scope, AssetsManager, $window) {
-
-    var darkThemeFiles = [
-      'css/accessibility/accessibilityHC.css'
-    ];
-
-    var fontSizeFiles = [
-      'css/accessibility/accessibilityFont.css'
-    ];
-
-    $scope.FONT_SIZE_PREF = "font_size_pref";
-    $scope.HC_THEME_PREF = "hc_theme_pref";
-
-    var doSwitch = function (check, files) {
-      if (!check) {
-        for (var i = 0; i < files.length; i++) {
-          AssetsManager.remove(files[i], "css");
-        }
-      } else {
-        for (var i = 0; i < files.length; i++) {
-          AssetsManager.inject(AssetsManager.accessibilityCssId + "_" + i, files[i], "css");
-        }
-      }
-    };
-
-    var savePreference = function (key, value) {
-      $window.localStorage.setItem(key, value);
-    };
-
-    var getPreference = function (key) {
-      var storageValue = $window.localStorage.getItem(key);
-      if (storageValue === null) {
-        savePreference(key, "false");
-      }
-      return storageValue === 'true';
-    };
-
-    $scope.isHighContrast = getPreference($scope.HC_THEME_PREF);
-    $scope.isIncreasedFont = getPreference($scope.FONT_SIZE_PREF);
-
-    $scope.checkPref = function (pref) {
-      switch (pref) {
-        case $scope.FONT_SIZE_PREF:
-          doSwitch($scope.isIncreasedFont, fontSizeFiles);
-          break;
-
-        case $scope.HC_THEME_PREF:
-          doSwitch($scope.isHighContrast, darkThemeFiles);
-          break;
-
-        default:
-          break;
-      }
-    };
-
-    $scope.switchTheme = function () {
-      $scope.isHighContrast = !$scope.isHighContrast;
-      doSwitch($scope.isHighContrast, darkThemeFiles);
-      savePreference($scope.HC_THEME_PREF, $scope.isHighContrast);
-    };
-
-    $scope.switchIncreasedFont = function () {
-      $scope.isIncreasedFont = !$scope.isIncreasedFont;
-      doSwitch($scope.isIncreasedFont, fontSizeFiles);
-      savePreference($scope.FONT_SIZE_PREF, $scope.isIncreasedFont);
-    };
-
-  }]);
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/HomeController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/HomeController.js
deleted file mode 100644
index 0470587..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/HomeController.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
- **/
-
-'use strict';
-
-angular.module("home").controller("HomeController", ['$scope', '$http', '$location', function ($scope, $http, $location) {
-  }]);
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js
deleted file mode 100644
index f92c15c..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-'use strict';
-angular.module("login").controller("LoginController", ['$scope', '$rootScope', '$http', '$state', '$location',
-  'AuthService',
-  function ($scope, $rootScope, $http, $state, $location, AuthService) {
-
-    $scope.credentials = {
-      username: '',
-      password: '',
-      errorMessage: ''
-    };
-
-    $scope.login = function (credentials) {
-      AuthService.login($scope.credentials).then(function (user) {
-        console.info("Login success for: ", user);
-        // reset error message
-        $scope.credentials.errorMessage = '';
-        // reset SAML 2.0 entityID
-        $rootScope.saml2idps.selected.entityID = null;
-        // reset OIDC name
-        $rootScope.oidcops.selected.name = null;
-        // got to update page
-        $state.go("update" + $rootScope.getWizardFirstStep());
-      }, function (response) {
-        console.info("Login failed for: ", response);
-        var errorMessage;
-        // parse error response 
-        if (response !== undefined) {
-          errorMessage = response.split("ErrorMessage{{")[1];
-          errorMessage = errorMessage.split("}}")[0];
-        }
-        $scope.credentials.errorMessage = "Login failed: " + errorMessage;
-        $scope.showError($scope.credentials.errorMessage, $scope.notification);
-      });
-    };
-
-    $scope.logout = function () {
-      window.location.href = '../wicket/bookmarkable/org.apache.syncope.client.enduser.pages.Logout';
-    };
-
-    $scope.islogged = function () {
-      AuthService.islogged().then(function (response) {
-        console.debug("user login status detected", response);
-        return response.data === true;
-      }, function (response) {
-        console.error("error retrieving user login status", response);
-      });
-    };
-
-    $scope.selfCreate = function () {
-      $state.go("create" + $rootScope.getWizardFirstStep());
-    };
-
-    $scope.passwordReset = function () {
-      $state.go("passwordreset");
-    };
-
-    $scope.$watch(function () {
-      return $location.search().successMessage;
-    }, function (successMessage) {
-      if (successMessage) {
-        var message = (' ' + successMessage).slice(1);
-        $scope.showSuccess(message, $scope.notification);
-        delete $location.$$search.successMessage;
-      }
-    });
-
-    $scope.$watch(function () {
-      return $location.search().errorMessage;
-    }, function (errorMessage) {
-      if (errorMessage) {
-        var message = (' ' + errorMessage).slice(1);
-        $scope.showError(message, $scope.notification);
-        delete $location.$$search.errorMessage;
-      }
-    });
-  }]);
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/OIDCClientController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/OIDCClientController.js
deleted file mode 100644
index 8d7b3cd..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/OIDCClientController.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-'use strict';
-angular.module("login").controller("OIDCClientController", function ($scope, $rootScope, $state, userAttrs) {
-  $scope.selfCreate = function () {
-    $state.go("create" + $rootScope.getWizardFirstStep());
-  };
-
-  $rootScope.oidcops.userAttrs = userAttrs;
-
-  $scope.selfCreate();
-});
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/SAML2SPController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/SAML2SPController.js
deleted file mode 100644
index 6d6bd33..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/SAML2SPController.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-'use strict';
-angular.module("login").controller("SAML2SPController", function ($scope, $rootScope, $state, userAttrs) {
-  $scope.selfCreate = function () {
-    $state.go("create" + $rootScope.getWizardFirstStep());
-  };
-
-  $rootScope.saml2idps.userAttrs = userAttrs;
-
-  $scope.selfCreate();
-});
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js
deleted file mode 100644
index d997542..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js
+++ /dev/null
@@ -1,678 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/* global message, component, $state, rootScope */
-
-'use strict';
-
-angular.module("self").controller("UserController", ['$scope', '$rootScope', '$location', "$state",
-  'UserSelfService', 'SchemaService', 'RealmService', 'ResourceService', 'SecurityQuestionService',
-  'GroupService', 'AnyService', 'BpmnProcessService', 'UserRequestsService', 'UserUtil', 'GenericUtil',
-  'ValidationExecutor', '$translate', '$filter',
-  function ($scope, $rootScope, $location, $state, UserSelfService, SchemaService, RealmService,
-          ResourceService, SecurityQuestionService, GroupService, AnyService, BpmnProcessService, UserRequestsService,
-          UserUtil, GenericUtil, ValidationExecutor, $translate, $filter) {
-
-    $scope.user = {};
-    $scope.confirmPassword = {
-      value: ''
-    };
-    $scope.userFormValid = false;
-    $scope.createMode = $location.path().indexOf("/self/create") > -1;
-
-    $scope.availableRealms = [];
-    $scope.availableSecurityQuestions = [];
-    $scope.bpmnProcesses = [];
-    $scope.userRequests = [];
-    $scope.userRequestsForms = [];
-
-    $scope.initialSecurityQuestion = '';
-    $scope.captchaInput = {
-      value: ""
-    };
-
-    /* <Extensions> */
-    $scope.loadFromSAML2AuthSelfReg = $rootScope.saml2idps.userAttrs && $rootScope.saml2idps.userAttrs.length;
-
-    $scope.loadFromOIDCAuthSelfReg = $rootScope.oidcops.userAttrs && $rootScope.oidcops.userAttrs.length;
-    /* </Extensions> */
-
-    $scope.initUser = function () {
-      $scope.dynamicForm = {
-        plainSchemas: [],
-        derSchemas: [],
-        virSchemas: [],
-        resources: [],
-        groups: [],
-        auxClasses: [],
-        anyUserType: [],
-        errorMessage: '',
-        attributeTable: {},
-        virtualAttributeTable: {},
-        selectedResources: [],
-        selectedGroups: [],
-        selectedAuxClasses: [],
-        groupSchemas: ['own']
-      };
-
-      var findLoadedSAML2AttrValue = function (schemaKey) {
-        var found = $filter('filter')($rootScope.saml2idps.userAttrs, {"schema": schemaKey}, true);
-        return (found && found.length && found[0].values && found[0].values.length)
-                ? found[0].values : [];
-      };
-
-      var findLoadedOIDCAttrValue = function (schemaKey) {
-        var found = $filter('filter')($rootScope.oidcops.userAttrs, {"schema": schemaKey}, true);
-        return (found && found.length && found[0].values && found[0].values.length)
-                ? found[0].values : [];
-      };
-
-      var initUserSchemas = function (anyTypeClass, group) {
-        // initialization is done here synchronously to have all schema fields populated correctly
-        var schemaService;
-        if (group) {
-          /* 
-           * if you want to sort with custom JS function defined in put also a sorting function as last parameter
-           * e.g. $rootScope.attributesSorting.ASC
-           */
-          schemaService = SchemaService.getTypeExtSchemas(group);
-        } else {
-          /* 
-           * if you want to sort with custom JS function defined in put also a sorting function as last parameter
-           * e.g. $rootScope.attributesSorting.ASC
-           */
-          schemaService = SchemaService.getUserSchemas(anyTypeClass);
-        }
-        schemaService.then(function (schemas) {
-          if (group && (schemas.plainSchemas.length > 0 || schemas.derSchemas.length > 0 || schemas.virSchemas.length > 0))
-            $scope.dynamicForm.groupSchemas.push(group);
-          /* 
-           * initializing user schemas values, i.e. USER attributes
-           */
-          initSchemaValues(schemas);
-        }, function (response) {
-          // parse error response and log
-          if (response !== undefined) {
-            var errorMessages = response.toString().split("ErrorMessage{{");
-            if (errorMessages.length > 1) {
-              console.error("Error retrieving user schemas: ", response.toString().split("ErrorMessage{{")[1].split("}}")[0]);
-            } else {
-              console.error("Error retrieving user schemas: ", errorMessages);
-            }
-          }
-        });
-      };
-
-      var initSchemaValues = function (schemas) {
-        // initialize plain attributes
-        for (var i = 0; i < schemas.plainSchemas.length; i++) {
-          var plainSchemaKey = schemas.plainSchemas[i].key;
-          var initialAttributeValues = $rootScope.customFormAttributes
-                  && $rootScope.customFormAttributes["PLAIN"]
-                  && $rootScope.customFormAttributes["PLAIN"]["attributes"]
-                  && $rootScope.customFormAttributes["PLAIN"]["attributes"][plainSchemaKey]
-                  && $rootScope.customFormAttributes["PLAIN"]["attributes"][plainSchemaKey].defaultValues
-                  ? $rootScope.customFormAttributes["PLAIN"]["attributes"][plainSchemaKey].defaultValues
-                  : [];
-          if (!$scope.user.plainAttrs[plainSchemaKey]) {
-            $scope.user.plainAttrs[plainSchemaKey] = {
-              schema: plainSchemaKey,
-              values: initialAttributeValues
-            };
-
-            if ($scope.loadFromSAML2AuthSelfReg) {
-              $scope.user.plainAttrs[plainSchemaKey].values = findLoadedSAML2AttrValue(plainSchemaKey);
-            }
-
-            if ($scope.loadFromOIDCAuthSelfReg) {
-              $scope.user.plainAttrs[plainSchemaKey].values = findLoadedOIDCAttrValue(plainSchemaKey);
-            }
-
-            if (schemas.plainSchemas[i].multivalue) {
-              // initialize multivalue schema and support table: create mode, default multivalues
-              if (initialAttributeValues.length > 0) {
-                // attribute create mode, init empty fields  
-                $scope.dynamicForm.attributeTable[plainSchemaKey] = {
-                  fields: []
-                };
-                for (var j = 0; j < initialAttributeValues.length; j++) {
-                  $scope.dynamicForm.attributeTable[plainSchemaKey].fields.push(plainSchemaKey + "_" + j);
-                }
-              } else {
-                // initialize multivalue schema and support table: create mode, only first value
-                $scope.dynamicForm.attributeTable[schemas.plainSchemas[i].key] = {
-                  fields: [schemas.plainSchemas[i].key + "_" + 0]
-                };
-              }
-            }
-          } else if (schemas.plainSchemas[i].multivalue) {
-            // initialize multivalue attribute and support table: update mode, all provided values
-            $scope.dynamicForm.attributeTable[schemas.plainSchemas[i].key] = {
-              fields: [schemas.plainSchemas[i].key + "_" + 0]
-            };
-            // add other values
-            for (var j = 1; j < $scope.user.plainAttrs[plainSchemaKey].values.length; j++) {
-              $scope.dynamicForm.attributeTable[schemas.plainSchemas[i].key].fields.
-                      push(schemas.plainSchemas[i].key + "_" + j);
-            }
-          }
-        }
-
-        // initialize derived attributes
-        for (var i = 0; i < schemas.derSchemas.length; i++) {
-          var derSchemaKey = schemas.derSchemas[i].key;
-          if (!$scope.user.derAttrs[derSchemaKey]) {
-            $scope.user.derAttrs[derSchemaKey] = {
-              schema: derSchemaKey,
-              values: []
-            };
-          }
-        }
-
-        // initialize virtual attributes
-        for (var i = 0; i < schemas.virSchemas.length; i++) {
-          var virSchemaKey = schemas.virSchemas[i].key;
-          if (!$scope.user.virAttrs[virSchemaKey]) {
-            $scope.user.virAttrs[virSchemaKey] = {
-              schema: virSchemaKey,
-              values: []
-            };
-
-            if ($scope.loadFromSAML2AuthSelfReg) {
-              $scope.user.virAttrs[virSchemaKey].values = findLoadedSAML2AttrValue(virSchemaKey);
-            }
-
-            if ($scope.loadFromOIDCAuthSelfReg) {
-              $scope.user.virAttrs[virSchemaKey].values = findLoadedOIDCAttrValue(virSchemaKey);
-            }
-
-            // initialize multivalue attribute and support table: create mode, only first value
-            $scope.dynamicForm.virtualAttributeTable[schemas.virSchemas[i].key] = {
-              fields: [schemas.virSchemas[i].key + "_" + 0]
-            };
-          } else {
-            // initialize multivalue attribute and support table: update mode, all provided values
-            $scope.dynamicForm.virtualAttributeTable[schemas.virSchemas[i].key] = {
-              fields: [schemas.virSchemas[i].key + "_" + 0]
-            };
-            // add other values
-            for (var j = 1; j < $scope.user.virAttrs[virSchemaKey].values.length; j++) {
-              $scope.dynamicForm.virtualAttributeTable[schemas.virSchemas[i].key].fields.
-                      push(schemas.virSchemas[i].key + "_" + j);
-            }
-          }
-        }
-        //appending new schemas
-        $scope.dynamicForm.plainSchemas = $scope.dynamicForm.plainSchemas.concat(schemas.plainSchemas);
-        $scope.dynamicForm.derSchemas = $scope.dynamicForm.derSchemas.concat(schemas.derSchemas);
-        $scope.dynamicForm.virSchemas = $scope.dynamicForm.virSchemas.concat(schemas.virSchemas);
-
-        //clean SAML Self Reg user attributes variable
-        delete $rootScope.saml2idps.userAttrs;
-
-        //clean OIDC Self Reg user attributes variable
-        delete $rootScope.oidcops.userAttrs;
-      };
-
-      var initSecurityQuestions = function () {
-        SecurityQuestionService.getAvailableSecurityQuestions().then(function (response) {
-          $scope.availableSecurityQuestions = response;
-        }, function (response) {
-          var errorMessage;
-          // parse error response 
-          if (response !== undefined) {
-            errorMessage = response.split("ErrorMessage{{")[1];
-            errorMessage = errorMessage.split("}}")[0];
-          }
-          console.error("Error retrieving avaliable security questions: ", errorMessage);
-        });
-      };
-
-      var initRealms = function () {
-        RealmService.getAvailableRealms().then(function (response) {
-          for (var i in response) {
-            $scope.availableRealms.push(response[i].fullPath);
-          }
-          $scope.availableRealms.sort();
-        });
-      };
-
-      var initResources = function () {
-        ResourceService.getResources().then(function (response) {
-          for (var i in response) {
-            $scope.dynamicForm.resources.push(response[i]);
-          }
-          $scope.dynamicForm.resources.sort();
-        });
-      };
-
-      var initGroups = function (service, selectElem) {
-        var realm = $scope.user.realm || "/";
-        var term = null;
-
-        if (selectElem && selectElem.search) {
-          term = selectElem.search;
-        } else {
-          service = "getGroups";
-        }
-
-        GroupService[service](realm, term).then(function (response) {
-          var newGroups = [];
-          if (!term) {
-            $scope.dynamicForm.groups = new Array();
-          }
-
-          $scope.dynamicForm.totGroups = response.totGroups;
-          for (var i in response.groupTOs) {
-            newGroups.push({
-              "groupKey": i,
-              "groupName": response["groupTOs"][i]
-            });
-          }
-          newGroups.sort(function (a, b) {
-            var x = a.groupName;
-            var y = b.groupName;
-            return x < y ? -1 : x > y ? 1 : 0;
-          });
-
-          if (service !== "getSearchedGroups") {
-            $scope.dynamicForm.groups = newGroups;
-          }
-          if (term) {
-            selectElem.refreshItems(newGroups);
-          }
-
-        }, function (e) {
-          $scope.showError("An error occur while retrieving groups " + e, $scope.notification);
-        });
-      };
-
-      $scope.refreshGroups = function () {
-        initGroups();
-      };
-
-      var initAuxClasses = function () {
-        //fetching default user classes, that should remain in any case
-        AnyService.getUserClasses().then(function (response) {
-          $scope.dynamicForm.anyUserType = response;
-          AnyService.getAuxClasses().then(function (response) {
-            for (var i = 0; i < response.length; i++) {
-              // we should only add schemas that aren't in the anyUserType
-              if ($scope.dynamicForm.anyUserType.indexOf(response[i]) === -1) {
-                $scope.dynamicForm.auxClasses.push(response[i]);
-              }
-            }
-          }, function (e) {
-            $scope.showError("An error occur while retrieving auxiliary classes " + e, $scope.notification);
-          });
-        }, function (e) {
-          $scope.showError("An error occur while retrieving auxiliary classes " + e, $scope.notification);
-        });
-      };
-
-      var initProperties = function () {
-        initRealms();
-        //retrieve security available questions
-        initSecurityQuestions();
-        //initialize available groups
-        initGroups();
-        //initialize available auxiliary classes
-        initAuxClasses();
-        // initialize user attributes starting from any object schemas
-        initUserSchemas();
-        // initialize available resources
-        initResources();
-      };
-
-      var readUser = function () {
-        UserSelfService.read().then(function (response) {
-          $scope.user = UserUtil.getUnwrappedUser(response);
-          $scope.user.password = undefined;
-
-          $scope.initialSecurityQuestion = $scope.user.securityQuestion;
-          // initialize already assigned resources
-          $scope.dynamicForm.selectedResources = $scope.user.resources;
-
-          // initialize already assigned groups -- keeping the same structure of groups       
-          for (var index in $scope.user.memberships) {
-            $scope.dynamicForm.selectedGroups.push(
-                    {
-                      "groupKey": $scope.user.memberships[index]["groupKey"].toString(),
-                      "groupName": $scope.user.memberships[index]["groupName"]
-                    });
-          }
-          //initialize already assigned auxiliary classes
-          $scope.dynamicForm.selectedAuxClasses = $scope.user.auxClasses;
-          //we need to initialize axiliar attribute schemas
-          for (var index in $scope.user.auxClasses) {
-            $scope.$emit("auxClassAdded", $scope.user.auxClasses[index]);
-          }
-          for (var index in $scope.user.memberships) {
-            $scope.$emit("groupAdded", $scope.user.memberships[index].groupName);
-          }
-          if ($scope.user.mustChangePassword) {
-            $state.go('mustchangepassword');
-          } else {
-            initProperties();
-          }
-        }, function (e) {
-          console.error("Error while user read ", e);
-        });
-      };
-
-      var removeUserSchemas = function (anyTypeClass, group) {
-        //removing plain groupSchemas
-        for (var i = 0; i < $scope.dynamicForm.groupSchemas.length; i++) {
-          if ($scope.dynamicForm.groupSchemas[i] === group) {
-            $scope.dynamicForm.groupSchemas.splice(i, 1);
-            i--;
-          }
-        }
-
-        //removing plain schemas
-        for (var i = 0; i < $scope.dynamicForm.plainSchemas.length; i++) {
-          if ((anyTypeClass && $scope.dynamicForm.plainSchemas[i].anyTypeClass === anyTypeClass)
-                  || (group && $scope.dynamicForm.plainSchemas[i].key.includes(group + '#'))) {
-            //cleaning both form and user model
-            delete $scope.user.plainAttrs[$scope.dynamicForm.plainSchemas[i].key];
-            $scope.dynamicForm.plainSchemas.splice(i, 1);
-            i--;
-          }
-        }
-
-        //removing derived schemas
-        for (var i = 0; i < $scope.dynamicForm.derSchemas.length; i++) {
-          if ((anyTypeClass && $scope.dynamicForm.derSchemas[i].anyTypeClass === anyTypeClass)
-                  || (group && $scope.dynamicForm.derSchemas[i].key.includes(group + '#'))) {
-            //cleaning both form and user model
-            delete $scope.user.derAttrs[$scope.dynamicForm.derSchemas[i].key];
-            $scope.dynamicForm.derSchemas.splice(i, 1);
-            i--;
-          }
-        }
-        //removing virtual schemas
-        for (var i = 0; i < $scope.dynamicForm.virSchemas.length; i++) {
-          if ((anyTypeClass && $scope.dynamicForm.virSchemas[i].anyTypeClass === anyTypeClass)
-                  || (group && $scope.dynamicForm.virSchemas[i].key.includes(group + '#'))) {
-            //cleaning both form and user model
-            delete $scope.user.virAttrs[$scope.dynamicForm.virSchemas[i].key];
-            $scope.dynamicForm.virSchemas.splice(i, 1);
-            i--;
-          }
-        }
-      };
-
-      //Event management
-      $scope.$on('auxClassAdded', function (event, auxClass) {
-        if (auxClass)
-          initUserSchemas(auxClass);
-      });
-
-      $scope.$on('auxClassRemoved', function (event, auxClass) {
-        if (auxClass)
-          removeUserSchemas(auxClass);
-      });
-
-      $scope.$on('groupAdded', function (event, group) {
-        if (group)
-          initUserSchemas(null, group);
-      });
-
-      $scope.$on('groupRemoved', function (event, group) {
-        if (group)
-          removeUserSchemas(null, group);
-      });
-
-      $scope.$on('groupSearched', function (event, selectElem) {
-        if (selectElem)
-          initGroups("getSearchedGroups", selectElem);
-      });
-
-      if ($scope.createMode) {
-        $scope.user = {
-          username: '',
-          password: '',
-          realm: '/',
-          securityQuestion: '',
-          securityAnswer: '',
-          plainAttrs: {},
-          derAttrs: {},
-          virAttrs: {},
-          resources: [],
-          auxClasses: []
-        };
-        // initialize auxiliary schemas in case of pre-existing classes
-        for (var index in $scope.dynamicForm.selectedAuxClasses) {
-          initUserSchemas($scope.dynamicForm.selectedAuxClasses[index]);
-        }
-        // initialize groups in case of pre-existing groups
-        for (var index in $scope.dynamicForm.selectedGroups) {
-          initUserSchemas(null, $scope.dynamicForm.selectedGroups[index]);
-        }
-        initProperties();
-
-        if ($scope.loadFromSAML2AuthSelfReg) {
-          var username = findLoadedSAML2AttrValue("username");
-          if (username.length) {
-            $scope.user.username = username[0];
-          }
-        }
-
-        if ($scope.loadFromOIDCAuthSelfReg) {
-          var username = findLoadedOIDCAttrValue("username");
-          if (username.length) {
-            $scope.user.username = username[0];
-          }
-        }
-      } else {
-        // read user from syncope core
-        readUser();
-      }
-    };
-
-    $scope.saveUser = function (user) {
-      var wrappedUser = UserUtil.getWrappedUser(user);
-      if ($scope.createMode) {
-        UserSelfService.create(wrappedUser, $scope.captchaInput.value).then(function (response) {
-          console.debug("User " + $scope.user.username + " successfully CREATED");
-          $rootScope.currentUser = $scope.user.username;
-          $rootScope.currentOp = "SUCCESSFULLY_CREATED";
-          $scope.success({
-            successMessage: $filter('translate')(["USER"]).USER
-                    + " "
-                    + $scope.user.username
-                    + " "
-                    + $filter('translate')(["SUCCESSFULLY_CREATED"]).SUCCESSFULLY_CREATED
-          });
-        }, function (response) {
-          console.error("Error during user creation: ", response);
-          var errorMessage;
-          // parse error response 
-          if (response !== undefined) {
-            errorMessage = response.split("ErrorMessage{{")[1];
-            errorMessage = errorMessage.split("}}")[0];
-          }
-          $scope.showError("Error: " + (errorMessage || response), $scope.notification);
-        });
-      } else {
-        UserSelfService.update(wrappedUser, $scope.captchaInput.value).then(function (response) {
-          console.debug("User " + $scope.user.username + " successfully UPDATED");
-          $rootScope.currentUser = $scope.user.username;
-          $rootScope.currentOp = "SUCCESSFULLY_UPDATED";
-          $scope.logout({
-            successMessage: $filter('translate')(["USER"]).USER
-                    + " "
-                    + $scope.user.username
-                    + " "
-                    + $filter('translate')(["SUCCESSFULLY_UPDATED"]).SUCCESSFULLY_UPDATED
-          });
-        }, function (response) {
-          console.error("Error during user update: ", response);
-          var errorMessage;
-          // parse error response 
-          if (response !== undefined) {
-            errorMessage = response.split("ErrorMessage{{")[1];
-            errorMessage = errorMessage.split("}}")[0];
-          }
-          $scope.showError("Error: " + (errorMessage || response), $scope.notification);
-        });
-      }
-    };
-
-    $scope.retrieveSecurityQuestion = function (user) {
-      if ($rootScope.pwdResetRequiringSecurityQuestions) {
-        if (user && user.username && user.username.length) {
-          return SecurityQuestionService.getSecurityQuestionByUser(user.username).then(function (data) {
-            $scope.userSecurityQuestion = data.content;
-          }, function (response) {
-            var errorMessage;
-            // parse error response 
-            if (response !== undefined) {
-              errorMessage = response.split("ErrorMessage{{")[1];
-              errorMessage = errorMessage.split("}}")[0];
-              $scope.userSecurityQuestion = "";
-            }
-            $scope.showError("Error retrieving user security question: " + errorMessage, $scope.notification);
-          });
-        } else {
-          $scope.userSecurityQuestion = "";
-        }
-      }
-    };
-
-    $scope.resetPassword = function (user) {
-      if (user && user.username) {
-        UserSelfService.passwordReset(user, $scope.captchaInput.value).then(function (data) {
-          $rootScope.currentUser = $scope.user.username;
-          $rootScope.currentOp = "PASSWORD_UPDATED";
-          $translate.use($scope.languages.selectedLanguage.code);
-          $scope.success({successMessage: $filter('translate')(["USER"]).USER
-                    + " "
-                    + $scope.user.username
-                    + " "
-                    + $filter('translate')(["SUCCESSFULLY_UPDATED"]).SUCCESSFULLY_UPDATED});
-        }, function (response) {
-          var errorMessage;
-          // parse error response 
-          if (response !== undefined) {
-            errorMessage = response.split("ErrorMessage{{")[1];
-            errorMessage = errorMessage.split("}}")[0];
-            $scope.showError("An error occured during password reset: " + errorMessage, $scope.notification);
-            //we need to refresh captcha after a valid request
-            $scope.$broadcast("refreshCaptcha");
-          }
-        });
-      } else {
-        $scope.showError("You should use a valid and non-empty username", $scope.notification);
-      }
-    };
-
-    $scope.confirmPasswordReset = function (user, event) {
-      //getting the enclosing form in order to access to its controller                
-      var currentForm = GenericUtil.getEnclosingFormController(event.target, $scope);
-      if (currentForm != null) {
-        //check if password and confirmPassword are equals using angular built-in validation
-        if (ValidationExecutor.validate(currentForm, $scope)) {
-          var token = $location.search().token;
-          if (user && user.password && token) {
-            UserSelfService.confirmPasswordReset({"newPassword": user.password, "token": token}).then(function (data) {
-              $translate.use($scope.languages.selectedLanguage.code);
-              $scope.success({successMessage: $filter('translate')(["PASSWORD_UPDATED"]).PASSWORD_UPDATED});
-            }, function (response) {
-              var errorMessage;
-              // parse error response 
-              if (response !== undefined) {
-                errorMessage = response.split("ErrorMessage{{")[1];
-                errorMessage = errorMessage.split("}}")[0];
-                $scope.showError("An error occured during password reset: " + errorMessage, $scope.notification);
-              }
-            });
-          } else {
-            $scope.showError("You should use a valid and non-empty password", $scope.notification);
-          }
-        }
-      }
-    };
-
-    $scope.changePassword = function (user, event) {
-      //getting the enclosing form in order to access to its controller                
-      var currentForm = GenericUtil.getEnclosingFormController(event.target, $scope);
-      if (currentForm != null) {
-        //check if password and confirmPassword are equals using angular built-in validation
-        if (ValidationExecutor.validate(currentForm, $scope)) {
-          if (user && user.password) {
-            UserSelfService.changePassword({"newPassword": user.password}).then(function (response) {
-              console.debug("User " + user.username + " password successfully CHANGED");
-              $scope.logout({
-                successMessage: $filter('translate')(["PASSWORD_UPDATED"]).PASSWORD_UPDATED
-              });
-            }, function (response) {
-              var errorMessage;
-              // parse error response 
-              if (response !== undefined) {
-                errorMessage = response.split("ErrorMessage{{")[1];
-                errorMessage = errorMessage.split("}}")[0];
-                $scope.showError("An error occured during password change: " + errorMessage, $scope.notification);
-              }
-            });
-          } else {
-            $scope.showError("You should use a valid and non-empty password", $scope.notification);
-          }
-        }
-      }
-    };
-
-    $scope.switchLanguage = function () {
-      $translate.use($rootScope.languages.selectedLanguage.code);
-      kendo.culture($rootScope.languages.selectedLanguage.code);
-    };
-
-    $scope.logout = function (params) {
-      $translate.use($scope.languages.selectedLanguage.code);
-      $rootScope.endReached = false;
-      var destination = params && params.successMessage
-              ? '../wicket/bookmarkable/org.apache.syncope.client.enduser.pages.Logout?successMessage=' + params.successMessage
-              : '../wicket/bookmarkable/org.apache.syncope.client.enduser.pages.Logout';
-      window.location.href = destination;
-    };
-
-    $scope.success = function (params) {
-      $rootScope.endReached = false;
-      var destination = params && params.successMessage
-              ? '../wicket/bookmarkable/org.apache.syncope.client.enduser.pages.HomePage?successMessage=' + params.successMessage
-              : '../wicket/bookmarkable/org.apache.syncope.client.enduser.pages.HomePage';
-      window.location.href = destination;
-    };
-
-    $scope.redirect = function () {
-      $translate.use($scope.languages.selectedLanguage.code);
-      $state.go('home');
-      $rootScope.endReached = false;
-    };
-
-    $scope.finish = function (message) {
-      console.info("finish");
-      if ($scope.createMode) {
-        $state.go('create.finish');
-      } else {
-        $state.go('update.finish');
-      }
-    };
-
-  }]);
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/auxClasses.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/auxClasses.js
deleted file mode 100644
index e4bf6ff..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/auxClasses.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-angular.module('self')
-        .directive('auxiliary', function () {
-          return {
-            restrict: 'E',
-            templateUrl: 'views/auxClasses.html',
-            scope: {
-              dynamicForm: "=form",
-              user: "="
-            },
-            controller: function ($scope, $filter) {
-
-              $scope.init = function () {
-                if (!$scope.user.auxClasses) {
-                  $scope.user.auxClasses = new Array();                  
-                }
-              };
-
-              $scope.addAuxClass = function (item, model) {
-                var auxClass = item;
-                $scope.user.auxClasses.push(auxClass);
-                $scope.$emit("auxClassAdded", auxClass);
-              };
-
-              $scope.removeAuxClass = function (item, model) {
-                var auxClassIndex = $scope.getIndex(item);
-                $scope.user.auxClasses.splice(auxClassIndex, 1);
-                $scope.$emit("auxClassRemoved", item);
-              };
-
-              $scope.getIndex = function (selectedAuxClass) {
-                var auxClassIndex = $scope.user.auxClasses.map(function (auxClassName) {
-                  return auxClassName;
-                }).indexOf(selectedAuxClass);
-                return auxClassIndex;
-              };
-
-            }
-          };
-        });
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/bpmnProcesses.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/bpmnProcesses.js
deleted file mode 100644
index 58c8e71..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/bpmnProcesses.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-angular.module('self').directive('bpmnProcesses', [function () {
-    return {
-      restrict: 'E',
-      templateUrl: 'views/bpmnProcesses.html',
-      scope: {
-      },
-      controller: function ($scope) {
-        $scope.bpmnProcesses = $scope.$parent.$parent.resolve.bpmnProcesses;
-        $scope.selectedProcesses = $scope.$parent.$parent.resolve.selectedProcesses;
-        $scope.toggleSelection =
-                function (bpmnProcessKey) {
-                  var index = $scope.selectedProcesses.indexOf(bpmnProcessKey);
-                  if (index > -1) {
-                    $scope.selectedProcesses.splice(index, 1);
-                  } else {
-                    $scope.selectedProcesses.push(bpmnProcessKey);
-                  }
-                };
-      }};
-  }]);
-
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/captcha.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/captcha.js
deleted file mode 100644
index 0e76abf..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/captcha.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-angular.module('self')
-        .directive('captcha', function () {
-          return {
-            restrict: 'E',
-            templateUrl: 'views/captcha.html',
-            scope: {
-              input: "=",
-              captchaEnabled: '=enabled'
-            },
-            controller: function ($scope) {
-              $scope.captchaUrl = '';
-
-              //initialize captcha
-              $scope.refreshCaptcha = function () {
-                $scope.captchaUrl = '../api/captcha' + '?' + new Date();
-              };
-
-              // initialize captcha
-              $scope.refreshCaptcha();
-
-              $scope.$on("refreshCaptcha", function () {
-                $scope.refreshCaptcha()
-              });
-            }
-          };
-        });
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttribute.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttribute.js
deleted file mode 100644
index a3581ed..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttribute.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-angular.module('self')
-        .directive('dynamicDerivedAttribute', function () {
-          return {
-            restrict: 'E',
-            templateUrl: 'views/dynamicDerivedAttribute.html',
-            scope: {
-              schema: "=",
-              index: "=",
-              user: "="
-            },
-            controller: function ($scope) {
-              $scope.$watch(function () {
-                return $scope.user.derAttrs[$scope.schema.key].values[$scope.index];
-              }, function (newValue, oldValue) {
-                $scope.user.derAttrs[$scope.schema.key].values = $scope.user.derAttrs[$scope.schema.key].values
-                        .filter(function (n) {
-                          return (n !== undefined && n !== "");
-                        });
-              });
-            },
-            //replace: true
-          };
-        });
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttributes.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttributes.js
deleted file mode 100644
index e1ecabc..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttributes.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-'use strict';
-
-angular.module('self')
-        .directive('dynamicDerivedAttributes', function () {
-          var getTemplateUrl = function () {
-            return 'views/dynamicDerivedAttributes.html';
-          };
-          return {
-            restrict: 'E',
-            templateUrl: getTemplateUrl(),
-            scope: {
-              dynamicForm: "=form",
-              user: "=",
-              language: "="
-            },
-            controller: function ($scope) {
-
-              $scope.getByGroup = function (group) {
-                var currentDerivedSchemas = new Array();
-                for (var i = 0; i < $scope.dynamicForm.derSchemas.length; i++) {
-                  var attr = $scope.dynamicForm.derSchemas[i];
-                  if (group === "own" && $scope.dynamicForm.derSchemas[i].key.indexOf('#') == -1) {
-                    attr.simpleKey = $scope.dynamicForm.derSchemas[i].key;
-                    currentDerivedSchemas.push(attr);
-                  } else {
-                    var prefix = $scope.dynamicForm.derSchemas[i].key.substr
-                            (0, $scope.dynamicForm.derSchemas[i].key.indexOf('#'));
-                    if (prefix === group)
-                    {
-                      var shaPosition = $scope.dynamicForm.derSchemas[i].key.indexOf("#") + 1;
-                      attr.simpleKey = $scope.dynamicForm.derSchemas[i].key.substring(shaPosition);
-                      currentDerivedSchemas.push(attr);
-                    }
-                  }
-                }
-                return currentDerivedSchemas;
-              };
-
-              $scope.addAttributeField = function (derSchemaKey) {
-                console.debug("Add DERIVED value:", derSchemaKey);
-                console.debug(" ", ($scope.dynamicForm.attributeTable[derSchemaKey].fields.length));
-                $scope.dynamicForm.attributeTable[derSchemaKey].fields.push(derSchemaKey + "_" + ($scope.dynamicForm.attributeTable[derSchemaKey].fields.length));
-              };
-
-              $scope.removeAttributeField = function (derSchemaKey, index) {
-                console.debug("Remove DERIVED value:", derSchemaKey);
-                console.debug("attribute index:", index);
-                $scope.dynamicForm.attributeTable[derSchemaKey].fields.splice(index, 1);
-                // clean user model
-                $scope.user.derAttrs[derSchemaKey].values.splice(index, 1);
-              };
-            }
-          };
-        });
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttribute.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttribute.js
deleted file mode 100644
index 7ed07e1..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttribute.js
+++ /dev/null
@@ -1,147 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-'use strict';
-angular.module('self')
-        .directive('dynamicPlainAttribute', function () {
-          return {
-            restrict: 'E',
-            templateUrl: 'views/dynamicPlainAttribute.html',
-            scope: {
-              schema: "=",
-              index: "=",
-              user: "="
-            },
-            controller: function ($scope, $rootScope, $element, $window) {
-              $scope.initAttribute = function (schema, index) {
-                switch (schema.type) {
-                  case "Long":
-                  case "Double":
-                    $scope.user.plainAttrs[schema.key].values[index] = Number($scope.user.plainAttrs[schema.key]
-                            .values[index]) || undefined;
-                    break;
-                  case "Enum":
-                    $scope.enumerationValues = [];
-                    $scope.enumerationKeys = [];
-
-                    //SYNCOPE-911 empty value option on non required attributes 
-                    if (schema.mandatoryCondition !== "true") {
-                      $scope.enumerationValues.push("");
-                      $scope.enumerationKeys.push("");
-                    }
-                    var enumerationValuesSplitted = schema.enumerationValues.toString().split(";");
-                    for (var i = 0; i < enumerationValuesSplitted.length; i++) {
-                      $scope.enumerationValues.push(enumerationValuesSplitted[i]);
-                    }
-                    //SYNCOPE-1024 enumeration keys mgmt
-                    if (schema.enumerationKeys) {
-                      var enumerationKeysSplitted = schema.enumerationKeys.toString().split(";");
-                      for (var i = 0; i < enumerationKeysSplitted.length; i++) {
-                        $scope.enumerationKeys.push(enumerationKeysSplitted[i]);
-                      }
-                    }
-                    $scope.user.plainAttrs[schema.key].values[index] = $scope.user.plainAttrs[schema.key].values[index]
-                            || $scope.enumerationValues[0];
-                    break;
-
-                  case "Binary":
-                    $scope.userFile = $scope.userFile || '';
-                    $element.bind("change", function (changeEvent) {
-                      $scope.$apply(function () {
-                        var reader = new FileReader();
-                        var file = changeEvent.target.files[0];
-                        $scope.userFile = file.name;
-                        reader.onload = function (readerEvt) {
-                          var binaryString = readerEvt.target.result;
-                          $scope.user.plainAttrs[schema.key].values[index] = btoa(binaryString);
-                        };
-                        reader.readAsBinaryString(file);
-                      });
-                    });
-
-                    $scope.download = function () {
-                      var byteString = atob($scope.user.plainAttrs[schema.key].values[index]);
-                      var ab = new ArrayBuffer(byteString.length);
-                      var ia = new Uint8Array(ab);
-                      for (var i = 0; i < byteString.length; i++) {
-                        ia[i] = byteString.charCodeAt(i);
-                      }
-                      var blob = new Blob([ia], {type: schema.mimeType});
-                      saveAs(blob, schema.key);
-                    };
-
-                    //file upload and preview                    
-                    $('#fileInput').on('fileclear', function () {
-                      $scope.user.plainAttrs[schema.key].values.splice(index, 1);
-                    });
-                    $scope.previewImg = $scope.user.plainAttrs[schema.key].values[index];
-                    break;
-
-                  case "Date":
-                    $scope.getType = function (x) {
-                      return typeof x;
-                    };
-                    $scope.isDate = function (x) {
-                      return x instanceof Date;
-                    };
-                    $scope.languageid = $rootScope.languages.selectedLanguage.id;
-                    $scope.isDateOnly = schema.conversionPattern.indexOf("H") === -1
-                            && schema.conversionPattern.indexOf("h") === -1;
-                    $scope.languageFormat = $scope.isDateOnly
-                            ? $rootScope.languages.selectedLanguage.format.replace(" HH:mm", "")
-                            : $rootScope.languages.selectedLanguage.format;
-                    $scope.languageCulture = $rootScope.languages.selectedLanguage.culture;
-                    // read date in milliseconds
-                    $scope.selectedDate = new Date($scope.user.plainAttrs[schema.key].values[index] * 1);
-
-                    $scope.bindDateToModel = function (selectedDate, extendedDate) {
-                      if (selectedDate) {
-                        // save date in milliseconds
-                        $scope.user.plainAttrs[schema.key].values[index] = new Date(extendedDate).getTime();
-                      }
-                    };
-                    break;
-
-                  case "Boolean":
-                    $scope.user.plainAttrs[schema.key].values[index] =
-                            $scope.user.plainAttrs[schema.key].values[index] === "true" ? "true" : "false";
-                    break;
-
-                }
-              };
-
-              $scope.customReadonly = function (schemaKey) {
-                return  $rootScope.customFormAttributes
-                        && $rootScope.customFormAttributes["PLAIN"]
-                        && $rootScope.customFormAttributes["PLAIN"]["attributes"]
-                        && $rootScope.customFormAttributes["PLAIN"]["attributes"][schemaKey]
-                        && $rootScope.customFormAttributes["PLAIN"]["attributes"][schemaKey].readonly;
-              };
-
-              $scope.$watch(function () {
-                return $scope.user.plainAttrs[$scope.schema.key].values[$scope.index];
-              }, function (newValue, oldValue) {
-                $scope.user.plainAttrs[$scope.schema.key].values = $scope.user.plainAttrs[$scope.schema.key].values
-                        .filter(function (n) {
-                          return (n !== undefined && n !== "");
-                        });
-              });
-            }
-          };
-        });
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttributes.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttributes.js
deleted file mode 100644
index 0dd1124..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttributes.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-angular.module('self')
-        .directive('dynamicPlainAttributes', function () {
-          var getTemplateUrl = function () {
-            return 'views/dynamicPlainAttributes.html';
-          };
-          return {
-            restrict: 'E',
-            templateUrl: getTemplateUrl(),
-            scope: {
-              dynamicForm: "=form",
-              user: "=",
-              language: "="
-            },
-            controller: function ($scope) {
-
-              $scope.getByGroup = function (group) {
-                var currentPlainSchemas = new Array();
-                for (var i = 0; i < $scope.dynamicForm.plainSchemas.length; i++) {
-                  var attr = $scope.dynamicForm.plainSchemas[i];
-                  if (group === "own" && $scope.dynamicForm.plainSchemas[i].key.indexOf('#') == -1) {
-                    attr.simpleKey = $scope.dynamicForm.plainSchemas[i].key;
-                    currentPlainSchemas.push(attr);
-                  } else {
-                    var prefix = $scope.dynamicForm.plainSchemas[i].key.substr
-                            (0, $scope.dynamicForm.plainSchemas[i].key.indexOf('#'));
-                    if (prefix === group)
-                    {
-                      var shaPosition = $scope.dynamicForm.plainSchemas[i].key.indexOf("#") + 1;
-                      attr.simpleKey = $scope.dynamicForm.plainSchemas[i].key.substring(shaPosition);
-                      currentPlainSchemas.push(attr);
-                    }
-                  }
-                }
-                return currentPlainSchemas;
-              };
-
-              $scope.addAttributeField = function (plainSchemaKey) {
-                console.debug("Add PLAIN value:", plainSchemaKey);
-                console.debug(" ", ($scope.dynamicForm.attributeTable[plainSchemaKey].fields.length));
-                $scope.dynamicForm.attributeTable[plainSchemaKey].fields.push(plainSchemaKey + "_" + ($scope.dynamicForm.attributeTable[plainSchemaKey].fields.length));
-              };
-
-              $scope.removeAttributeField = function (plainSchemaKey, index) {
-                console.debug("Remove PLAIN value:", plainSchemaKey);
-                console.debug("attribute index:", index);
-                $scope.dynamicForm.attributeTable[plainSchemaKey].fields.splice(index, 1);
-                // clean user model
-                $scope.user.plainAttrs[plainSchemaKey].values.splice(index, 1);
-              };
-
-              $scope.getTemplateUrl = function () {
-                return "views/dynamicPlainAttributes.html";
-              };
-            }
-          };
-        });
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicTemplateItem.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicTemplateItem.js
deleted file mode 100644
index f822106..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicTemplateItem.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-'use strict';
-
-angular.module('self')
-        .directive('dynamicTemplateItem', ['$rootScope', '$compile', '$http', 'AssetsManager',
-          function ($rootScope, $compile, $http, AssetsManager) {
-
-            var checkGeneralAssets = function () {
-              $rootScope.getDynamicTemplateOtherInfo("generalAssets", "css", function (assets) {
-                if (assets && assets.length) {
-                  for (var i = 0; i < assets.length; i++) {
-                    if (!AssetsManager.checkAlreadyLoaded(assets[i], "css")) {
-                      AssetsManager.inject("asset_general_css_" + i, assets[i], "css");
-                    }
-                  }
-                }
-              });
-            };
-
-            var linker = function ($scope, $element, $attrs) {
-              // compile template
-              $rootScope.getDynamicTemplateInfo($attrs.type, "templateUrl", function (templateUrl) {
-                if (templateUrl) {
-                  $http.get(templateUrl).then(function (response) {
-                    $element.html(response.data).show();
-                    $compile($element.contents())($scope);
-                  }, function (e) {
-                    console.error(e);
-                  });
-                }
-              });
-
-              // inject template assets
-              $rootScope.getDynamicTemplateInfo($attrs.type, "css", function (assets) {
-                if (assets && assets.length) {
-                  for (var i = 0; i < assets.length; i++) {
-                    AssetsManager.inject("asset_css_" + i, assets[i], "css");
-                  }
-                }
-              });
-
-              // remove useless assets for little optimization
-              if ($attrs.type !== "login") {
-                $rootScope.getDynamicTemplateInfo("login", "css", function (assets) {
-                  for (var i = 0; i < assets.length; i++) {
-                    AssetsManager.remove(assets[i], "css");
-                  }
-                });
-              }
-
-              // check general assets are always loaded (in case page refreshing in wizard)
-              checkGeneralAssets();
-            };
-
-            return {
-              restrict: "E",
-              link: linker,
-              replace: true
-            };
-
-          }]);
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttribute.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttribute.js
deleted file mode 100644
index 5a1d82c..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttribute.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-angular.module('self')
-        .directive('dynamicVirtualAttribute', function () {
-          return {
-            restrict: 'E',
-            templateUrl: 'views/dynamicVirtualAttribute.html',
-            scope: {
-              schema: "=",
-              index: "=",
-              user: "="
-            },
-            controller: function ($scope, $rootScope) {
-              var customValues = $rootScope.customFormAttributes
-                      && $rootScope.customFormAttributes["VIRTUAL"]
-                      && $rootScope.customFormAttributes["VIRTUAL"]["attributes"]
-                      && $rootScope.customFormAttributes["VIRTUAL"]["attributes"][$scope.schema.key]
-                      && $rootScope.customFormAttributes["VIRTUAL"]["attributes"][$scope.schema.key].defaultValues
-                      ? $rootScope.customFormAttributes["VIRTUAL"]["attributes"][$scope.schema.key].defaultValues
-                      : [];
-
-              $scope.$watch(function () {
-                return $scope.user.virAttrs[$scope.schema.key].values[$scope.index];
-              }, function (newValue, oldValue) {
-                if ($scope.user.virAttrs[$scope.schema.key].values
-                        && $scope.user.virAttrs[$scope.schema.key].values.length > 0) {
-                  $scope.user.virAttrs[$scope.schema.key].values = $scope.user.virAttrs[$scope.schema.key].values
-                          .filter(function (n) {
-                            return (n !== undefined && n !== "");
-                          });
-                } else {
-                  $scope.user.virAttrs[$scope.schema.key].values = customValues
-                          .filter(function (n) {
-                            return (n !== undefined && n !== "");
-                          });
-                }
-              });
-
-              $scope.customReadonly = function (schemaKey) {
-                return  $rootScope.customFormAttributes
-                        && $rootScope.customFormAttributes["VIRTUAL"]
-                        && $rootScope.customFormAttributes["VIRTUAL"]["attributes"]
-                        && $rootScope.customFormAttributes["VIRTUAL"]["attributes"][schemaKey]
-                        && $rootScope.customFormAttributes["VIRTUAL"]["attributes"][schemaKey].readonly;
-              };
-            }
-            //replace: true
-          };
-
-        });
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttributes.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttributes.js
deleted file mode 100644
index 8532bef..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttributes.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-'use strict';
-
-angular.module('self')
-        .directive('dynamicVirtualAttributes', function () {
-          var getTemplateUrl = function () {
-            return 'views/dynamicVirtualAttributes.html';
-          };
-          return {
-            restrict: 'E',
-            templateUrl: getTemplateUrl(),
-            scope: {
-              dynamicForm: "=form",
-              user: "=",
-              language: "="
-            },
-            controller: function ($scope) {
-
-              $scope.getByGroup = function (group) {
-                var currentVirtualSchemas = new Array();
-                for (var i = 0; i < $scope.dynamicForm.virSchemas.length; i++) {
-                  var attr = $scope.dynamicForm.virSchemas[i];
-                  if (group === "own" && $scope.dynamicForm.virSchemas[i].key.indexOf('#') == -1) {
-                    attr.simpleKey = $scope.dynamicForm.virSchemas[i].key;
-                    currentVirtualSchemas.push(attr);
-                  } else {
-                    var prefix = $scope.dynamicForm.virSchemas[i].key.substr
-                            (0, $scope.dynamicForm.virSchemas[i].key.indexOf('#'));
-                    if (prefix === group)
-                    {
-                      var shaPosition = $scope.dynamicForm.virSchemas[i].key.indexOf("#") + 1;
-                      attr.simpleKey = $scope.dynamicForm.virSchemas[i].key.substring(shaPosition);
-                      currentVirtualSchemas.push(attr);
-                    }
-                  }
-                }
-                return currentVirtualSchemas;
-              };
-
-              $scope.addVirtualAttributeField = function (virSchemaKey) {
-                $scope.dynamicForm.virtualAttributeTable[virSchemaKey].fields.push(virSchemaKey + "_"
-                        + ($scope.dynamicForm.virtualAttributeTable[virSchemaKey].fields.length));
-              };
-
-              $scope.removeVirtualAttributeField = function (virSchemaKey, index) {
-                $scope.dynamicForm.virtualAttributeTable[virSchemaKey].fields.splice(index, 1);
-                // clean user model
-                $scope.user.virAttrs[virSchemaKey].values.splice(index, 1);
-              };
-            }
-          };
-        });
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/fileInput.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/fileInput.js
deleted file mode 100644
index 331c0f4..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/fileInput.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-'use strict';
-angular.module('self')
-        .directive('fileInput', ['$rootScope', function ($rootScope) {
-            return {
-              restrict: 'A',
-              link: function ($scope, element, attrs) {
-                var previewImgComposite;
-                if ($scope.previewImg) {
-                  previewImgComposite = "data:image/png;base64," + $scope.previewImg;
-                } else
-                  previewImgComposite = null;
-                $(element).fileinput({
-                  showUpload: false,
-                  showCaption: false,
-                  showCancel: false,
-                  showClose: true,
-                  showRemove: false,
-                  fileActionSettings: {'showZoom': false, indicatorNew: '', 'removeTitle': 'boh'},
-                  removeClass: "btn btn-secondary btn-default",
-                  browseClass: "btn btn-secondary btn-default",
-                  browseLabel: '',
-                  dragIcon: '',
-                  browseIcon: '',
-                  initialPreviewAsData: true,
-                  overwriteInitial: true,
-//                maxFileCount: 1,
-//                'previewFileType': 'any',
-                  initialPreview: [
-                    previewImgComposite
-                  ],
-                  'maxFileSize': $rootScope.maxUploadFileSizeMB ? parseInt($rootScope.maxUploadFileSizeMB) * 1000 : undefined
-                });
-              }
-            };
-          }]);
-        
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/formProperty.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/formProperty.js
deleted file mode 100644
index 39ad82a..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/formProperty.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-angular.module('self')
-        .directive('formProperty', ['$rootScope', function ($rootScope) {
-            return {
-              restrict: 'E',
-              templateUrl: 'views/formProperty.html',
-              scope: {
-                property: "="
-              },
-              controller: function ($scope) {
-                $scope.initAttribute = function () {
-                  switch ($scope.property.type) {
-                    case "Long":
-                      $scope.property.value = Number($scope.property.value) || undefined;
-                      break;
-                    case "Enum":
-                      if ($scope.property.required !== "true") {
-                        $scope.property.enumValues.empty = "";
-                      }
-                      $scope.enumKeys = Object.keys($scope.property.enumValues);
-                      $scope.property.value = $scope.property.value || $scope.property.enumValues.empty;
-                      break;
-                    case "Dropdown":
-                      if ($scope.property.required !== "true") {
-                        $scope.property.dropdownValues.empty = "";
-                      }
-                      $scope.dropdownKeys = Object.keys($scope.property.dropdownValues);
-                      $scope.property.value = $scope.property.value || $scope.property.dropdownValues.empty;
-                      break;
-                    case "Date":
-                      $scope.getType = function (x) {
-                        return typeof x;
-                      };
-                      $scope.isDate = function (x) {
-                        return x instanceof Date;
-                      };
-                      $scope.languageid = $rootScope.languages.selectedLanguage.id;
-                      $scope.isDateOnly = $scope.property.datePattern.indexOf("H") === -1
-                              && $scope.property.datePattern.indexOf("h") === -1;
-                      $scope.languageFormat = $scope.isDateOnly
-                              ? $rootScope.languages.selectedLanguage.format.replace(" HH:mm", "")
-                              : $rootScope.languages.selectedLanguage.format;
-                      $scope.languageCulture = $rootScope.languages.selectedLanguage.culture;
-                      // read date in milliseconds
-                      $scope.selectedDate = $scope.property.value === null
-                              ? undefined
-                              : new Date($scope.property.value * 1);
-                      $scope.bindDateToModel = function (selectedDate, extendedDate) {
-                        if (selectedDate) {
-                          // save date in milliseconds
-                          $scope.property.value = new Date(extendedDate).getTime();
-                        }
-                      };
-                      break;
-                    case "Boolean":
-                      $scope.property.value = $scope.property.value === "true" ? "true" : "false";
-                      break;
-
-                  }
-                };
-
-              }
-            };
-          }]);
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/groups.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/groups.js
deleted file mode 100644
index af1fd99..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/groups.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-angular.module('self')
-        .directive('groups', ['GroupService', function (GroupService) {
-            return {
-              restrict: 'E',
-              templateUrl: 'views/groups.html',
-              scope: {
-                dynamicForm: "=form",
-                user: "="
-              },
-              controller: function ($scope, $filter, $timeout) {
-                var groupsSearchTimer;
-
-                $scope.init = function () {
-                  if (!$scope.user.memberships) {
-                    $scope.user.memberships = new Array();
-                  }
-                };
-
-                $scope.addGroup = function (item, model) {
-                  var membership = item;
-                  $scope.user.memberships.push({"groupKey": membership.groupKey, "groupName": membership.groupName});
-                  $scope.$emit("groupAdded", membership.groupName);
-                };
-
-                $scope.removeGroup = function (item, model) {
-                  var groupIndex = $scope.getIndex(item);
-                  var membership = $scope.user.memberships[groupIndex];
-                  var groupName = membership.groupName;
-                  $scope.user.memberships.splice(groupIndex, 1);
-                  $scope.$emit("groupRemoved", groupName);
-                };
-
-                $scope.onGroupsSearch = function (totGroups) {
-                  if (groupsSearchTimer) {
-                    $timeout.cancel(groupsSearchTimer);
-                  }
-                  if (totGroups > 30) {
-                    var that = this;
-                    groupsSearchTimer = $timeout(function () {
-                      $scope.$emit("groupSearched", that.$select);
-                    }, 800);
-                  }
-                };
-
-                $scope.getIndex = function (selectedGroup) {
-                  var groupIndex = $scope.user.memberships.map(function (membership) {
-                    return membership.groupName;
-                  }).indexOf(selectedGroup.groupName);
-                  return groupIndex;
-                };
-              }
-            };
-          }]);
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/loader.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/loader.js
deleted file mode 100644
index 603fb34..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/loader.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-'use strict';
-
-angular.module('SyncopeEnduserApp')
-        .directive("loader", function ($rootScope) {
-          return function ($scope, element, attrs) {
-            $scope.$on("loader_show", function () {
-              return element.show();
-            });
-            return $scope.$on("loader_hide", function () {
-              return element.hide();
-            });
-          };
-        });
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/modalContent.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/modalContent.js
deleted file mode 100644
index f0aed20..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/modalContent.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-angular.module('self').directive('modalContent', ['$compile', function ($compile) {
-    return {
-      restrict: 'E',
-      scope: {
-        modalHtml: "="
-      },
-      replace: true,
-      link: function ($scope, element, attrs) {
-        var template = $compile($scope.modalHtml)($scope);
-        element.replaceWith(template);
-      }};
-  }]);
-
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/modalWindow.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/modalWindow.js
deleted file mode 100644
index 3ad18e9..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/modalWindow.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-angular.module('self').directive('modalWindow', [function () {
-    return {
-      restrict: 'E',
-      templateUrl: 'views/modalWindow.html',
-      scope: {
-        resolve: '<',
-        close: '&',
-        dismiss: '&'
-      },
-      controller: function ($scope) {
-        $scope.init = function () {
-          // Please provide an init logic, by default do nothing
-        };
-
-        $scope.ok = function () {
-          $scope.close({$value: $scope.resolve.result});
-        };
-
-        $scope.cancel = function () {
-          $scope.dismiss({$value: 'cancel'});
-        };
-
-      }};
-  }]);
-
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/navigationButtonsPartial.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/navigationButtonsPartial.js
deleted file mode 100644
index 67a70d5..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/navigationButtonsPartial.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-angular.module('self')
-        .directive('navigationButtonsPartial', ['$state', 'GenericUtil', 'ValidationExecutor',
-          function ($state, GenericUtil, ValidationExecutor) {
-            return {
-
-              restrict: 'E',
-              templateUrl: 'views/navigationButtonsPartial.html',
-              scope: {
-                base: "@",
-                current: "@"
-              },
-              link: function (scope, element, attrs) {
-                var base = (scope.base && scope.base !== "" ? scope.base + "." : "");
-                scope.wizard = scope.$eval(attrs.wizard) || scope.$parent.wizard || scope.$parent.$parent.wizard;
-                scope.previous = "none";
-                if (scope.wizard) {
-                  var urls = Object.keys(scope.wizard);
-                  var index = urls.indexOf(scope.current);
-                  scope.previous = (index > 0 ? base + urls[index - 1] : scope.previous = "none");
-                  scope.next = (index < urls.length - 1 ? base + urls[index + 1] : scope.next = "none");
-                }
-              },
-              controller: function ($scope) {
-                $scope.validateAndNext = function ($event, state) {
-                  //getting the enclosing form in order to access to its name                
-                  var currentForm = GenericUtil.getEnclosingForm($event.target);
-                  if (currentForm !== null) {
-                    if (ValidationExecutor.validate(currentForm, $scope.$parent)) {
-                      if (state) {
-                        $scope.nextTab(state);
-                      } else if ($scope.wizard) {
-                        $scope.nextTab($scope.next);
-                      }
-                    }
-                  }
-                };
-
-                $scope.nextTab = function (state) {
-                  //change route through parent event
-                  $state.go(state);
-                };
-
-                $scope.previousTab = function () {
-                  //change route through parent event
-                  $state.go($scope.previous);
-                };
-              }
-
-            };
-          }]);
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/ngEnter.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/ngEnter.js
deleted file mode 100644
index 4f7e5a9..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/ngEnter.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-angular.module('self')
-        .directive('ngEnter', function ($parse) {
-
-          return function (scope, element, attrs) {
-            element.bind("keydown keypress", function (event) {
-              // check enter key pressed
-              if (event.which === 13) {
-                scope.$apply(function () {
-                  $parse(attrs.ngEnter)(scope, {
-                    $event: event
-                  });
-                });
-
-                event.preventDefault();
-              }
-            });
-          };
-
-        });
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/passwordStrengthEstimator.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/passwordStrengthEstimator.js
deleted file mode 100644
index 4bf52b2..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/passwordStrengthEstimator.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-'use strict'
-
-angular.module('self', [])
-        .directive('checkStrength', function () {
-          return {
-            replace: false,
-            restrict: 'EACM',
-            link: function (scope, iElement, iAttrs) {
-
-              var strength = {
-                colors: ['#F00', '#F90', '#FF0', '#9F0', '#0F0'],
-                mesureStrength: function (p) {
-
-                  var _force = 0;
-                  var _regex = /[$-/:-?{-~!"^_`\[\]]/g;
-
-                  var _lowerLetters = /[a-z]+/.test(p);
-                  var _upperLetters = /[A-Z]+/.test(p);
-                  var _numbers = /[0-9]+/.test(p);
-                  var _symbols = _regex.test(p);
-
-                  var _flags = [_lowerLetters, _upperLetters, _numbers, _symbols];
-                  var _passedMatches = $.grep(_flags, function (el) {
-                    return el === true;
-                  }).length;
-
-                  _force += 2 * p.length + ((p.length >= 10) ? 1 : 0);
-                  _force += _passedMatches * 10;
-
-                  // penality (short password)
-                  _force = (p.length <= 6) ? Math.min(_force, 10) : _force;
-
-                  // penality (poor variety of characters)
-                  _force = (_passedMatches == 1) ? Math.min(_force, 10) : _force;
-                  _force = (_passedMatches == 2) ? Math.min(_force, 20) : _force;
-                  _force = (_passedMatches == 3) ? Math.min(_force, 40) : _force;
-
-                  return _force;
-
-                },
-                getColor: function (s) {
-
-                  var idx = 0;
-                  if (s <= 10) {
-                    idx = 0;
-                  }
-                  else if (s <= 20) {
-                    idx = 1;
-                  }
-                  else if (s <= 30) {
-                    idx = 2;
-                  }
-                  else if (s <= 40) {
-                    idx = 3;
-                  }
-                  else {
-                    idx = 4;
-                  }
-
-                  return {idx: idx + 1, col: this.colors[idx]};
-
-                }
-              };
-
-              scope.$watch(iAttrs.checkStrength, function () {
-                if (scope.pw === '') {
-                  iElement.css({"display": "none"});
-                } else {
-                  var strength = strength.mesureStrength(scope.pw);
-                  var c = strength.getColor(strength);
-                  iElement.css({"display": "inline"});
-                  iElement.children('li')
-                          .css({"background": "#DDD"})
-                          .slice(0, c.idx)
-                          .css({"background": c.col});
-                }
-              });
-
-            },
-            template: ''
-          };
-        });
-
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/requestForms.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/requestForms.js
deleted file mode 100644
index 4512257..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/requestForms.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-angular.module('self')
-        .directive('requestForms', ['UserRequestsService',
-          function (UserRequestsService) {
-            return {
-              restrict: 'E',
-              templateUrl: 'views/requestForms.html',
-              scope: {
-                user: "="
-              },
-              controller: function ($scope) {
-                // Initialization
-                $scope.query = {
-                  user: $scope.user.username,
-                  page: 1,
-                  size: 10
-                };
-
-                var calculatePages = function () {
-                  $scope.totalPages = Math.ceil($scope.forms.totalCount / $scope.query.size);
-                  $scope.pages = _.range(1, $scope.totalPages + 1);
-                };
-
-                // <Pagination>
-                $scope.reloadPage = function (page, size, successMsg) {
-                  // update query pagination parameters
-                  $scope.query.page = page;
-                  $scope.query.size = size;
-                  // recalculate pages
-                  calculatePages();
-                  if (page < 1 || page > $scope.totalPages) {
-                    return;
-                  }
-                  // get current page of items
-
-                  $scope.getUserRequestForms($scope.query, function (forms) {
-                    $scope.forms = forms;
-                    $scope.$parent.showSuccess(successMsg, $scope.$parent.notification);
-                  });
-                };
-                // </Pagination>
-
-                var init = function () {
-                  $scope.getUserRequestForms({
-                    user: $scope.user.username,
-                    page: 1,
-                    size: 10
-                  }, function (requestsForms) {
-                    $scope.forms = requestsForms;
-                    calculatePages();
-                    $scope.availableSizes = [{id: 1, value: 10}, {id: 2, value: 25}, {id: 3, value: 50}];
-                    $scope.selectedSize = $scope.availableSizes[0];
-                  });
-                };
-
-                $scope.getUserRequestForms = function (query, callback) {
-                  UserRequestsService.getUserRequestForms(query).then(function (response) {
-                    callback(response);
-                  }, function (response) {
-                    var errorMessage;
-                    // parse error response 
-                    if (response !== undefined) {
-                      errorMessage = response.split("ErrorMessage{{")[1];
-                      errorMessage = errorMessage.split("}}")[0];
-                    }
-                    console.error("Error retrieving User Request Forms: ", errorMessage);
-                  });
-                };
-
-                init();
-
-                $scope.submit = function (form) {
-                  UserRequestsService.submitForm(form).then(function (response) {
-                    console.debug("Form successfully submitted");
-                    $scope.$parent.showSuccess("Form successfully submitted", $scope.$parent.notification);
-                    $scope.reloadPage($scope.query.page, $scope.query.size, "Form successfully submitted");
-                  }, function (response) {
-                    var errorMessage;
-                    // parse error response 
-                    if (response !== undefined) {
-                      errorMessage = response.split("ErrorMessage{{")[1];
-                      errorMessage = errorMessage.split("}}")[0];
-                    }
-                    console.error("Error retrieving User Request Forms: ", errorMessage);
-                    $scope.$parent.showError("Error: " + (errorMessage || response), $scope.$parent.notification);
-                  });
-
-                };
-              }
-            };
-          }]);
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/requests.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/requests.js
deleted file mode 100644
index 64d15a5..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/requests.js
+++ /dev/null
@@ -1,192 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-angular.module('self')
-        .directive('requests', ['UserRequestsService', 'BpmnProcessService', "$uibModal", "$document", '$filter',
-          '$rootScope',
-          function (UserRequestsService, BpmnProcessService, $uibModal, $document, $filter, $rootScope) {
-            return {
-              restrict: 'E',
-              templateUrl: 'views/requests.html',
-              scope: {
-                user: "="
-              },
-              controller: function ($scope) {
-                // Initialization
-                $scope.query = {
-                  user: $scope.user.username,
-                  page: 1,
-                  size: 10
-                };
-
-                var calculatePages = function () {
-                  $scope.totalPages = Math.ceil($scope.requests.totalCount / $scope.query.size);
-                  $scope.pages = _.range(1, $scope.totalPages + 1);
-                };
-
-                // <Pagination>
-                $scope.reloadPage = function (page, size, successMsg) {
-                  // update query pagination parameters
-                  $scope.query.page = page;
-                  $scope.query.size = size;
-                  // recalculate pages
-                  calculatePages();
-                  if (page < 1 || page > $scope.totalPages) {
-                    return;
-                  }
-                  // get current page of items
-
-                  $scope.getUserRequests($scope.query, function (requests) {
-                    $scope.requests = requests;
-                    if (successMsg) {
-                      $scope.$parent.showSuccess(successMsg, $scope.$parent.notification);
-                    }
-                  });
-                };
-                // </Pagination>
-
-                $scope.getUserRequests = function (query, callback) {
-                  UserRequestsService.getUserRequests(query).then(function (response) {
-                    callback(response);
-                  }, function (response) {
-                    var errorMessage;
-                    // parse error response 
-                    console.log("ERROR ", response);
-                    if (response !== undefined) {
-                      errorMessage = response.split("ErrorMessage{{")[1];
-                      errorMessage = errorMessage.split("}}")[0];
-                    }
-                    console.error("Error retrieving User Requests: ", errorMessage);
-                    $scope.$parent.showError("Error: " + (errorMessage || response), $scope.$parent.notification);
-                  });
-                };
-
-                var init = function () {
-                  $scope.requests = [];
-                  $scope.getUserRequests($scope.query, function (requests) {
-                    $scope.requests = requests;
-                    calculatePages();
-                    $scope.availableSizes = [{id: 1, value: 10}, {id: 2, value: 25}, {id: 3, value: 50}];
-                    $scope.selectedSize = $scope.availableSizes[0];
-                    // date formatting
-                    $scope.formatDate = $rootScope.formatDate;
-                  });
-
-                };
-
-                var initBpmnProcesses = function () {
-                  $scope.bpmnProcesses = [];
-                  BpmnProcessService.getBpmnProcesses().then(function (response) {
-                    $scope.bpmnProcesses = response;
-                  }, function (response) {
-                    // parse error response and log
-                    if (response !== undefined) {
-                      var errorMessages = response.toString().split("ErrorMessage{{");
-                      if (errorMessages.length > 1) {
-                        console.error("Error retrieving BPMN Processes: ", response.toString()
-                                .split("ErrorMessage{{")[1].split("}}")[0]);
-                      } else {
-                        console.error("Error retrieving BPMN Processes: ", errorMessages);
-                      }
-                    }
-                  });
-                };
-
-                init();
-                initBpmnProcesses();
-
-                $scope.cancel = function (request, reason) {
-                  console.log("Cancel request ", request.executionId, reason);
-                  UserRequestsService.cancel(request.executionId, reason).then(function (response) {
-                    var index = $scope.requests.result.indexOf(request);
-                    if (index > -1) {
-                      $scope.requests.result.splice(index, 1);
-                      $scope.requests.totalCount--;
-                      $scope.reloadPage($scope.query.page, $scope.query.size, 
-                      "Process " + request.executionId + " successfully canceled");
-                    }
-                  }, function (response) {
-                    var errorMessage;
-                    // parse error response 
-                    if (response !== undefined) {
-                      errorMessage = response.split("ErrorMessage{{")[1];
-                      errorMessage = errorMessage.split("}}")[0];
-                    }
-                    console.error("Error canceling User Request: ", request.executionId, errorMessage);
-                  });
-                };
-
-                $scope.openComponentModal = function (size, parentSelector) {
-                  $scope.selectedProcesses = [];
-                  var parentElem = parentSelector ?
-                          angular.element($document[0].querySelector(parentSelector)) : undefined;
-                  var modalInstance = $uibModal.open({
-                    animation: true,
-                    ariaLabelledBy: 'modal-title',
-                    ariaDescribedBy: 'modal-body',
-                    component: 'modalWindow',
-                    appendTo: parentElem,
-                    size: size,
-                    windowClass: 'in',
-                    backdropClass: 'in',
-                    resolve: {
-                      bpmnProcesses: function () {
-                        return $scope.bpmnProcesses;
-                      },
-                      selectedProcesses: function () {
-                        return $scope.selectedProcesses;
-                      },
-                      modalHtml: function () {
-                        return '<bpmn-processes></bpmn-processes>';
-                      },
-                      title: function () {
-                        return $filter('translate')(["SELECT_PROCESS"]).SELECT_PROCESS;
-                      }
-                    }
-                  });
-
-                  modalInstance.result.then(function () {
-                    for (var i = 0; i < $scope.selectedProcesses.length; i++) {
-                      startRequest(i);
-                    }
-                  }, function () {
-                  });
-                };
-
-                var startRequest = function (i) {
-                  var currentProc = $scope.selectedProcesses[i];
-                  UserRequestsService.start(currentProc).then(function (response) {
-                    console.log("Process " + currentProc + " successfully started");
-                    $scope.reloadPage($scope.query.page, $scope.query.size,
-                            "Process " + currentProc + " successfully started");
-                  }, function (response) {
-                    var errorMessage;
-                    // parse error response 
-                    if (response !== undefined) {
-                      errorMessage = response.split("ErrorMessage{{")[1];
-                      errorMessage = errorMessage.split("}}")[0];
-                    }
-                    $scope.$parent.showError("Error: " + (errorMessage || response), $scope.$parent.notification);
-                    console.error("Error starting User Request: ", errorMessage);
-                  });
-                };
-              }
-            };
-          }]);
\ No newline at end of file
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/resources.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/resources.js
deleted file mode 100644
index bf1a822..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/resources.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-angular.module('self')
-        .directive('resources', function () {
-          return {
-            restrict: 'E',
-            templateUrl: 'views/resources.html',
-            scope: {
-              dynamicForm: "=form",
-              user: "="
-            },
-            controller: function ($scope, $filter) {
-              $scope.addResource = function (item, model) {
-                var resource = item;
-                $scope.user.resources.push(resource);
-              };
-
-              $scope.removeResource = function (item, model) {
-                var resourceIndex = $scope.getIndex(item);
-                $scope.user.resources.splice(resourceIndex, 1);
-
-              };
-
-              $scope.getIndex = function (selectedResource) {
-                var resourceIndex = $scope.user.resources.map(function (resourceName) {
-                  return resourceName;
-                }).indexOf(selectedResource);
-                return resourceIndex;
-              };
-
-            }
-          };
-        });
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/validate.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/validate.js
deleted file mode 100644
index e3526b3..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/validate.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-'use strict';
-
-//Live validation
-angular.module('SyncopeEnduserApp').
-        directive('validate', function () {
-          return {
-            require: 'ngModel',
-            link: function (scope, elem, attrs, ngModel) {
-              scope.$watch(attrs.ngModel, function (value) {
-                //trigger the live validation only if user interacts with the input
-                var validationEnabled = scope.validationEnabled || scope.$root.validationEnabled;
-                if (validationEnabled && !ngModel.$pristine) {
-                  //broadcasting from root scope element validity
-                  scope.$root.$broadcast(attrs.name, {errors: ngModel.$error});
-                }
-              });
-            }
-          };
-        });
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/validateDropdown.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/validateDropdown.js
deleted file mode 100644
index 9dd49db..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/validateDropdown.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-'use strict';
-
-//Live validation
-angular.module('SyncopeEnduserApp').
-        directive('validateDropdown', ['$timeout', function ($timeout) {
-
-            return {
-              restrict: 'A',
-              require: 'ngModel',
-              replace: true,
-
-              link: function ($scope, $elem, attrs, ngModel) {
-
-                $scope.dynamicform = $scope.$eval(attrs.dynamicForm);
-                var dropdownSelectName = attrs.validateDropdown;
-
-                var realmTemp;
-                var isGroups = dropdownSelectName === "groups";
-                if (isGroups) {
-                  realmTemp = $scope.user.realm;
-                }
-
-                // enable / disable input according to available values
-                $scope.$watch(attrs.dynamicForm + "." + dropdownSelectName, function (newValues) {
-                  // disable input element when no data is available (groups, resources, etc...)
-                  if (newValues && newValues.length > 0) {
-                    $scope.$parent.inputDisabled = false;
-                  } else {
-                    $scope.$parent.inputDisabled = true;
-                  }
-                  // to solve some graphical rerendering issues
-                  $timeout(function () {
-                    $elem.trigger('click');
-                  }, 100);
-
-                  // remove selected groups when realm changes
-                  if (isGroups && realmTemp !== $scope.user.realm) {
-                    // remove group list only whether selected groups are not in realms
-
-                    for (var item in $scope.dynamicform.selectedGroups) {
-                      var filtered = newValues.filter(function (e) {
-                        return $scope.dynamicform.selectedGroups[item] &&
-                                e.groupName === $scope.dynamicform.selectedGroups[item].groupName;
-                      });
-                      if (filtered.length === 0) {
-                        $scope.$parent.removeGroup($scope.dynamicform.selectedGroups[item], $scope.ngModel);
-                        $scope.dynamicform.selectedGroups = _.without($scope.dynamicform.selectedGroups,
-                                $scope.dynamicform.selectedGroups[item]);
-                      }
-                    }
-                    realmTemp = $scope.user.realm;
-                  }
-                });
-
-              }
-
-            };
-          }]);
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/validationMessage.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/validationMessage.js
deleted file mode 100644
index 158578d..0000000
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/validationMessage.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-'use strict';
-
-angular.module('SyncopeEnduserApp').
-        directive('validationMessage', function () {
-          return {
-            templateUrl: 'views/validationMessage.html',
-            scope: {
-              "name": "@",
-              "template": "@"
-            },
-            require: '^?form',
-            replace: false,
-            link: function (scope, el, attrs, formCtrl) {
-              var popupMessage = "Data are invalid: please correct accordingly";
-              //listener
-              scope.$on(attrs.name, function (el, errors) {
-                scope.errors = errors;
-                //hide popup error message if there aren't errors
-                if ($.isEmptyObject(formCtrl.$error)) {
-                  scope.$emit("hideErrorMessage", popupMessage);
-                }
-              });
-            }
... 6425 lines suppressed ...


Mime
View raw message