syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ilgro...@apache.org
Subject [syncope] branch master updated: [SYNCOPE-1418] All based on Spring Boot now
Date Mon, 21 Jan 2019 07:24:02 GMT
This is an automated email from the ASF dual-hosted git repository.

ilgrosso 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 f201793  [SYNCOPE-1418] All based on Spring Boot now
f201793 is described below

commit f201793ab9b9a08bf87aa2064a9e090145cc9ef8
Author: Francesco Chicchiriccò <ilgrosso@apache.org>
AuthorDate: Mon Jan 21 08:23:49 2019 +0100

    [SYNCOPE-1418] All based on Spring Boot now
---
 archetype/pom.xml                                  |   27 +-
 .../resources/archetype-resources/console/pom.xml  |   86 +-
 .../resources/archetype-resources/core/pom.xml     |  108 +--
 .../resources/archetype-resources/enduser/pom.xml  |   96 +-
 archetype/src/main/resources/meta-pom.xml          |   11 +-
 client/enduser/pom.xml                             |   42 +-
 .../client/enduser/SyncopeEnduserApplication.java  |  366 +------
 .../client/enduser/SyncopeEnduserSession.java      |   14 +-
 ...Application.java => SyncopeWebApplication.java} |   23 +-
 .../enduser/adapters/PlatformInfoAdapter.java      |    8 +-
 .../client/enduser/init/EnduserInitializer.java    |   51 -
 .../client/enduser/resources/BaseResource.java     |    6 +-
 .../enduser/resources/DynamicTemplateResource.java |    4 +-
 .../resources/ExternalResourceResource.java        |    4 +-
 .../client/enduser/resources/GroupResource.java    |    4 +-
 .../client/enduser/resources/InfoResource.java     |    4 +-
 .../client/enduser/resources/LoginResource.java    |    4 +-
 .../client/enduser/resources/SchemaResource.java   |    6 +-
 .../enduser/resources/UserSelfCreateResource.java  |    4 +-
 .../enduser/resources/UserSelfReadResource.java    |    4 +-
 .../enduser/resources/UserSelfUpdateResource.java  |    4 +-
 .../src/main/resources/META-INF/web-fragment.xml   |   46 -
 .../src/main/resources/application.properties      |   17 +-
 ...DirectoryPanelAditionalActionLinksProvider.java |    2 +
 .../commons/IdMExternalResourceProvider.java       |    2 +
 .../client/console/commons/IdMStatusProvider.java  |    2 +
 .../commons/IdMVirSchemaDetailsPanelProvider.java  |    2 +
 client/idrepo/console/pom.xml                      |   45 +-
 .../console/BookmarkablePageLinkBuilder.java       |    2 +-
 .../client/console/SyncopeConsoleApplication.java  |  362 +------
 .../client/console/SyncopeConsoleSession.java      |   12 +-
 ...Application.java => SyncopeWebApplication.java} |   21 +-
 ...DirectoryPanelAditionalActionLinksProvider.java |    3 +-
 ...DirectoryPanelAditionalActionLinksProvider.java |    2 +
 .../commons/EmptyExternalResourceProvider.java     |    2 +
 .../console/commons/EmptyStatusProvider.java       |    2 +
 .../EmptyVirSchemaDetailsPanelProvider.java        |    2 +
 .../console/commons/ExternalResourceProvider.java  |    3 +-
 .../client/console/commons/PreviewUtils.java       |   24 +-
 .../client/console/commons/StatusProvider.java     |    3 +-
 .../commons/VirSchemaDetailsPanelProvider.java     |    3 +-
 .../client/console/init/ConsoleInitializer.java    |   56 --
 .../syncope/client/console/pages/BasePage.java     |    9 +-
 .../syncope/client/console/pages/Dashboard.java    |    9 +-
 .../apache/syncope/client/console/pages/Login.java |   20 +-
 .../console/panels/AnyObjectDirectoryPanel.java    |    4 +-
 .../console/panels/DashboardOverviewPanel.java     |   12 +-
 .../client/console/panels/GroupDirectoryPanel.java |    4 +-
 .../console/panels/ImplementationModalPanel.java   |   34 +-
 .../panels/ParametersCreateWizardSchemaStep.java   |   10 +-
 .../client/console/panels/PlainSchemaDetails.java  |    9 +-
 .../syncope/client/console/panels/Realm.java       |    6 +-
 .../client/console/panels/RealmDetails.java        |    4 +-
 .../console/panels/SchemaTypeWizardBuilder.java    |    6 +-
 .../client/console/panels/UserDirectoryPanel.java  |    4 +-
 .../console/panels/search/AbstractSearchPanel.java |    4 +-
 .../console/policies/PolicyModalPanelBuilder.java  |    4 +-
 .../wicket/markup/html/form/AjaxDownload.java      |    9 +-
 .../wicket/markup/html/form/BinaryFieldPanel.java  |   15 +-
 .../wicket/markup/html/form/ImageModalPanel.java   |    1 -
 .../console/widgets/ReconciliationWidget.java      |    8 +-
 .../syncope/client/console/wizards/AjaxWizard.java |    4 +-
 .../console/wizards/any/AnyWizardBuilder.java      |    4 +-
 .../syncope/client/console/wizards/any/Groups.java |    4 +-
 .../client/console/wizards/any/Ownership.java      |    4 +-
 .../client/console/wizards/any/Resources.java      |    6 +-
 .../syncope/client/console/wizards/any/Roles.java  |    6 +-
 .../client/console/wizards/any/StatusPanel.java    |    4 +-
 .../src/main/resources/META-INF/web-fragment.xml   |   46 -
 .../src/main/resources/application.properties      |   17 +-
 ...properties => SyncopeWebApplication.properties} |    0
 ...perties => SyncopeWebApplication_it.properties} |    0
 ...perties => SyncopeWebApplication_ja.properties} |    0
 ...ties => SyncopeWebApplication_pt_BR.properties} |    0
 ...perties => SyncopeWebApplication_ru.properties} |    0
 .../client/console/widgets/CompletenessWidget.html |    1 -
 .../apache/syncope/common/lib/PropertyUtils.java   |    8 +-
 .../syncope/common/lib/request/DomainCR.java       |  197 ++++
 .../apache/syncope/core/logic/AnyTypeLogic.java    |    3 +-
 .../org/apache/syncope/core/logic/LoggerLogic.java |    5 +-
 .../apache/syncope/core/logic/LogicContext.java    |   69 ++
 .../org/apache/syncope/core/logic/TaskLogic.java   |    3 +-
 .../init/ClassPathScanImplementationLookup.java    |    4 +-
 .../syncope/core/logic/init/EntitlementLoader.java |   24 +-
 .../syncope/core/logic/init/LoggerLoader.java      |   75 +-
 .../syncope/core/logic/init/LogicInitializer.java  |   69 --
 .../src/main/resources/META-INF/spring.factories   |    5 +-
 .../logic/src/main/resources/logic.properties      |    2 +
 .../logic/src/main/resources/logicContext.xml      |   46 -
 core/idrepo/rest-cxf/pom.xml                       |   23 +-
 .../apache/syncope/core/rest/cxf/JavaDocUtils.java |   11 +
 .../syncope/core/rest/cxf/RESTCXFContext.java      |   39 +
 .../core/rest/cxf/RestServiceExceptionMapper.java  |    6 +-
 .../core/rest/cxf/SyncopeOpenApiCustomizer.java    |   44 +-
 .../syncope/core/rest/cxf/WADLInitializer.java     |   42 +
 .../apache/syncope/core/rest/cxf/WADLServlet.java  |    4 +-
 .../syncope/core/rest/cxf/WadlGenerator.java       |   27 +-
 .../src/main/resources/META-INF/spring.factories   |    6 +-
 .../src/main/resources/META-INF/web-fragment.xml   |   82 --
 .../rest-cxf/src/main/resources/restCXFContext.xml |    8 -
 core/persistence-api/pom.xml                       |    7 +-
 .../core/persistence/api/ImplementationLookup.java |    2 +-
 .../{SyncopeLoader.java => SyncopeCoreLoader.java} |   23 +-
 .../{ContentLoader.java => ContentDealer.java}     |    4 +-
 .../persistence/api/content/ContentExporter.java   |    9 +-
 .../persistence/api/content/ContentLoader.java     |    5 +-
 core/persistence-jpa-json/pom.xml                  |    4 +
 .../core/persistence/jpa/DomainConfFactory.java    |  153 +++
 .../syncope/core/persistence/jpa/DomainLoader.java |  105 ++
 .../syncope/core/persistence/jpa/MasterDomain.java |  184 ++++
 .../core/persistence/jpa/PersistenceContext.java   |  186 ++++
 .../jpa/content/AbstractContentDealer.java         |   35 -
 .../jpa/content/XMLContentExporter.java            |   20 +-
 .../persistence/jpa/content/XMLContentLoader.java  |   86 +-
 .../core/persistence/jpa/dao/JPADerSchemaDAO.java  |    2 +
 .../jpa/entity/anyobject/JPAAPlainAttr.java        |    2 +-
 .../persistence/jpa/entity/conf/JPACPlainAttr.java |    2 +-
 .../jpa/entity/group/JPAGPlainAttr.java            |    2 +-
 .../persistence/jpa/entity/user/JPAUPlainAttr.java |    2 +-
 ...java => DomainTransactionAnnotationParser.java} |   26 +-
 .../jpa/spring/DomainTransactionInterceptor.java   |   20 +-
 .../DomainTransactionInterceptorInjector.java      |    9 +-
 .../src/main/resources/META-INF/spring.factories   |   10 +-
 .../persistence-jpa/src/main/resources/domains.xml |   61 --
 .../src/main/resources/domains/MasterDomain.xml    |  110 ---
 .../src/main/resources/persistenceContext.xml      |   54 --
 .../syncope/core/persistence/jpa/AbstractTest.java |    2 +-
 .../persistence/jpa/DummyImplementationLookup.java |    8 +-
 .../persistence/jpa/PersistenceTestContext.java    |   70 ++
 .../core/persistence/jpa/TestInitializer.java      |   39 +-
 .../persistence/jpa/outer/PlainSchemaTest.java     |   12 +-
 .../src/test/resources/domains/Two.properties      |    2 +-
 .../src/test/resources/domains/TwoDomain.xml       |  110 ---
 .../src/test/resources/persistenceTest.xml         |   55 --
 core/pom.xml                                       |    1 +
 .../core/provisioning/java/ConnectorLoader.java}   |   21 +-
 .../core/provisioning/java/ConnectorManager.java   |    8 +-
 .../provisioning/java/ProvisioningContext.java     |  109 +++
 .../core/provisioning/java/job/JobManagerImpl.java |  126 ++-
 .../DefaultNotificationJobDelegate.java            |    2 +-
 .../java/pushpull/AbstractPullResultHandler.java   |   15 +-
 .../src/main/resources/META-INF/spring.factories   |    5 +-
 .../src/main/resources/provisioningContext.xml     |   17 -
 .../core/provisioning/java/AbstractTest.java       |    7 +-
 .../java/DummyImplementationLookup.java            |    7 +-
 .../provisioning/java/ProvisioningTestContext.java |   41 +
 .../core/provisioning/java/TestInitializer.java    |   39 +-
 .../src/test/resources/provisioningTest.xml        |   63 --
 core/spring/pom.xml                                |    9 +
 .../core/spring/ApplicationContextProvider.java    |    4 +
 .../syncope/core/spring/security/Encryptor.java    |    2 +-
 .../core/spring/security/SecurityContext.java      |  124 +++
 .../src/main/resources/META-INF/spring.factories   |    5 +-
 core/spring/src/main/resources/securityContext.xml |   47 +-
 .../spring/security/DummyImplementationLookup.java |    7 +-
 core/{spring => starter}/pom.xml                   |   98 +-
 .../core/starter/SyncopeCoreApplication.java       |   58 ++
 .../core/starter/SyncopeCoreInitializer.java       |   69 ++
 .../src/main/resources/application.properties      |   16 +-
 core/upgrade/pom.xml                               |    2 +-
 core/upgrade/src/assemble/upgrade-zip.xml          |   10 +-
 .../core/workflow/java/WorkflowContext.java        |   65 ++
 .../src/main/resources/META-INF/spring.factories   |    5 +-
 .../src/main/resources/workflowContext.xml         |   29 -
 deb/console/pom.xml                                |   52 +-
 deb/console/src/deb/control/conffiles              |    5 -
 deb/core/pom.xml                                   |   92 +-
 deb/core/src/deb/control/conffiles                 |   15 -
 deb/core/src/deb/tomcat8/syncope.xml               |    2 +-
 deb/enduser/pom.xml                                |   38 +-
 deb/enduser/src/deb/control/conffiles              |    7 -
 docker/console/LICENSE                             |  889 +++++++++++++++++
 docker/console/NOTICE                              |  151 +++
 docker/console/pom.xml                             |   91 +-
 docker/console/src/main/resources/Dockerfile       |   21 +-
 docker/console/src/main/resources/build.sh         |   58 --
 .../src/main/resources/console.properties.template |    7 +-
 .../console}/src/main/resources/log4j2.xml         |   35 +-
 .../resources/oidcclient-agent.properties.template |    2 +-
 .../resources/saml2sp-agent.properties.template    |    2 +-
 docker/console/src/main/resources/startup.sh       |   12 +-
 docker/core/LICENSE                                | 1016 ++++++++++++++++++++
 docker/core/NOTICE                                 |  160 +++
 docker/core/pom.xml                                |  224 ++++-
 docker/core/src/main/resources/Dockerfile          |   30 +-
 docker/core/src/main/resources/build.sh            |   60 --
 .../{ => domains}/Master.properties.mariadb        |    0
 .../{ => domains}/Master.properties.mssql          |    0
 .../{ => domains}/Master.properties.mysql          |    0
 .../Master.properties.pgjsonb}                     |    2 +-
 .../{ => domains}/Master.properties.postgresql     |    0
 docker/core/src/main/resources/indexes.xml.pgjsonb |   63 ++
 .../core}/src/main/resources/log4j2.xml            |  114 +--
 .../core/src/main/resources/persistence.properties |    2 +-
 ...e.properties => persistence.properties.pgjsonb} |   20 +-
 .../main/resources/provisioning.properties.mariadb |    2 +
 .../main/resources/provisioning.properties.mssql   |    2 +
 .../main/resources/provisioning.properties.mysql   |    2 +
 ....postgresql => provisioning.properties.pgjsonb} |    3 +
 .../resources/provisioning.properties.postgresql   |    2 +
 docker/core/src/main/resources/startup.sh          |   21 +-
 docker/core/src/main/resources/views.xml.pgjsonb   |  154 +++
 docker/enduser/LICENSE                             |  772 +++++++++++++++
 docker/enduser/NOTICE                              |  138 +++
 docker/enduser/pom.xml                             |   82 +-
 docker/enduser/src/main/resources/Dockerfile       |   23 +-
 docker/enduser/src/main/resources/build.sh         |   58 --
 .../src/main/resources/enduser.properties.template |    2 +-
 .../enduser}/src/main/resources/log4j2.xml         |   28 +-
 .../resources/oidcclient-agent.properties.template |    2 +-
 .../resources/saml2sp-agent.properties.template    |    2 +-
 docker/enduser/src/main/resources/startup.sh       |   12 +-
 docker/pom.xml                                     |    5 +
 .../docker-compose/docker-compose-pgjsonb.yml      |   70 ++
 .../syncope/core/logic/init/CamelRouteLoader.java  |   28 +-
 ext/camel/provisioning-camel/pom.xml               |    4 +
 .../camel/CamelUserProvisioningManager.java        |    3 +-
 .../camel/ProvisioningCamelContext.java            |   65 ++
 .../src/main/resources/META-INF/spring.factories   |    5 +-
 .../main/resources/provisioningCamelContext.xml    |   48 -
 .../client/ElasticsearchClientContext.java         |   61 ++
 .../client/ElasticsearchClientFactoryBean.java     |    1 -
 .../src/main/resources/META-INF/spring.factories   |    5 +-
 .../main/resources/elasticsearchClientContext.xml  |   51 -
 ext/flowable/client-console/pom.xml                |    2 +-
 ext/flowable/flowable-bpmn/pom.xml                 |    5 +
 .../core/flowable/WorkflowFlowableContext.java     |  128 +++
 .../flowable/impl/FlowableUserRequestHandler.java  |    4 -
 .../support/DomainProcessEngineFactoryBean.java    |   81 +-
 .../src/main/resources/META-INF/spring.factories   |    5 +-
 .../src/main/resources/workflowFlowableContext.xml |   66 --
 .../syncope/core/logic/UserWorkflowTaskLogic.java  |    2 +
 .../syncope/core/logic/init/FlowableLoader.java    |   32 +-
 ext/oidcclient/agent/pom.xml                       |    5 +
 .../syncope/ext/oidcclient/agent/BeforeLogout.java |    2 -
 .../syncope/ext/oidcclient/agent/CodeConsumer.java |    2 -
 .../apache/syncope/ext/oidcclient/agent/Login.java |    2 -
 .../syncope/ext/oidcclient/agent/Logout.java       |    3 -
 .../oidcclient/agent/OIDCClientAgentContext.java   |   53 +
 .../ext/oidcclient/agent/OIDCClientAgentSetup.java |    5 +-
 .../src/main/resources/META-INF/spring.factories   |    5 +-
 ...IDCClientClassPathScanImplementationLookup.java |   17 +-
 .../syncope/core/logic/init/OIDCClientLoader.java  |   23 +-
 ext/saml2sp/agent/pom.xml                          |    7 +-
 .../ext/saml2lsp/agent/AssertionConsumer.java      |    2 -
 .../apache/syncope/ext/saml2lsp/agent/Login.java   |    2 -
 .../apache/syncope/ext/saml2lsp/agent/Logout.java  |    2 -
 .../syncope/ext/saml2lsp/agent/Metadata.java       |    2 -
 .../ext/saml2lsp/agent/SAML2SPAgentContext.java    |   53 +
 .../ext/saml2lsp/agent/SAML2SPAgentSetup.java      |    5 +-
 .../src/main/resources/META-INF/spring.factories   |    5 +-
 .../SAML2SPClassPathScanImplementationLookup.java  |   16 +-
 .../syncope/core/logic/init/SAML2SPLoader.java     |   34 +-
 .../apache/syncope/core/logic/init/SCIMLoader.java |    7 +-
 .../syncope/ext/scimv2/cxf/RESTSCIMCXFContext.java |   22 +-
 .../src/main/resources/META-INF/spring.factories   |    5 +-
 .../src/main/resources/META-INF/web-fragment.xml   |   70 --
 .../src/main/resources/restSCIMv2CXFContext.xml    |   44 +-
 ext/swagger-ui/pom.xml                             |    7 +-
 .../ext/swaggerui/SwaggerUIInitializer.java        |   15 +-
 .../src/main/resources/META-INF/spring.factories   |    5 +-
 fit/build-tools/pom.xml                            |  175 ++--
 .../src/assemble/jar-with-connid-bundles.xml       |   34 +-
 .../fit/buildtools/ApacheDSRootDseServlet.java     |    3 +-
 .../fit/buildtools/ApacheDSStartStopListener.java  |    4 +-
 ....java => ConnectorServerStartStopListener.java} |   42 +-
 .../fit/buildtools/H2StartStopListener.java        |    8 +-
 .../fit/buildtools/ServiceTimeoutServlet.java      |    2 +
 .../buildtools/SyncopeBuildToolsApplication.java   |   60 ++
 .../fit/buildtools/cxf/ProvisioningImpl.java       |    4 +-
 .../resources/META-INF/cxf/org.apache.cxf.Logger   |    1 -
 .../src/main/resources/application.properties      |   16 +-
 .../src/main/resources/buildToolsContext.xml       |   41 +-
 fit/build-tools/src/main/resources/cxfContext.xml  |   75 --
 .../src/main/webapp/WEB-INF/glassfish-web.xml      |    4 +-
 .../webapp/WEB-INF/jboss-deployment-structure.xml  |    4 +-
 fit/build-tools/src/main/webapp/WEB-INF/web.xml    |   55 +-
 fit/console-reference/pom.xml                      |  180 +---
 .../resources/application-embedded.properties}     |    4 +-
 .../src/main/resources/application.properties      |   17 +-
 .../src/main/resources/context.xml                 |   25 -
 .../src/main/resources/log4j2.xml                  |    4 +-
 .../src/main/webapp/WEB-INF/web.xml                |   12 +-
 .../src/main/webapp/WEB-INF/weblogic.xml           |   35 -
 fit/core-reference/pom.xml                         |  463 +++------
 .../core/logic/init/CoreReferenceLoader.java       |   12 +-
 .../fit/core/reference/ITImplementationLookup.java |   18 +-
 .../main/resources/all/saml2sp-logic.properties    |    3 +-
 .../main/resources/application-embedded.properties |   19 +-
 .../main/resources/application-wildfly.properties  |   13 +-
 ...2sp-logic.properties => application.properties} |   16 +-
 fit/core-reference/src/main/resources/context.xml  |   25 -
 .../src/main/resources/coreContext.xml             |   59 --
 .../src/main/resources/elasticsearch/web.xml       |   50 -
 .../src/main/resources/jboss/domains.xml           |   61 --
 .../main/resources/jboss/domains/MasterDomain.xml  |  116 ---
 .../src/main/resources/jboss/domains/TwoDomain.xml |  116 ---
 .../src/main/resources/jboss/restCXFContext.xml    |  193 ----
 .../src/main/resources/jboss/web.xml               |   49 -
 fit/core-reference/src/main/resources/log4j2.xml   |    6 +-
 .../src/main/resources/logic.properties            |    2 +
 .../main/resources/mysql/domains/Master.properties |    2 +-
 .../src/main/resources/userWorkflow.bpmn20.xml     |   74 +-
 .../webapp/WEB-INF/jboss-deployment-structure.xml  |    2 +-
 fit/core-reference/src/main/webapp/WEB-INF/web.xml |   26 +-
 fit/core-reference/src/main/webapp/cacheStats.jsp  |  191 ----
 fit/core-reference/src/main/webapp/db.jsp          |   35 -
 .../syncope/fit/console/AbstractConsoleITCase.java |   78 +-
 .../apache/syncope/fit/console/ConsoleSetup.java   |   47 -
 .../fit/core/AbstractNotificationTaskITCase.java   |   32 +-
 .../syncope/fit/core/MultitenancyITCase.java       |    2 +-
 .../apache/syncope/fit/core/PullTaskITCase.java    |    2 +-
 .../org/apache/syncope/fit/core/SCIMITCase.java    |    2 +-
 .../src/test/resources/hotswap-agent.properties    |    3 -
 fit/enduser-reference/pom.xml                      |  208 +---
 .../resources/application-embedded.properties}     |    4 +-
 .../src/main/resources/application.properties      |   17 +-
 .../src/main/resources/context.xml                 |   25 -
 .../src/main/webapp/WEB-INF/web.xml                |    7 +-
 .../src/main/webapp/WEB-INF/weblogic.xml           |   35 -
 pom.xml                                            |  169 +++-
 src/main/asciidoc/getting-started/obtain.adoc      |    8 +-
 .../getting-started/systemRequirements.adoc        |    2 +-
 .../reference-guide/concepts/extensions.adoc       |    6 +-
 .../adminconsole/adminconsole.adoc                 |    4 +-
 .../workingwithapachesyncope/customization.adoc    |   14 +-
 .../workingwithapachesyncope/enduser.adoc          |    4 +-
 .../workingwithapachesyncope/restfulservices.adoc  |    4 +-
 .../configurationparameters.adoc                   |    4 +-
 .../configureconnidlocations.adoc                  |    3 +-
 .../systemadministration/dbcp.adoc                 |   37 -
 .../systemadministration/domainsmanagement.adoc    |    2 +-
 .../systemadministration/emailconfiguration.adoc   |    2 +-
 .../systemadministration/executable.adoc           |   57 ++
 .../systemadministration/javaeecontainer.adoc      |   27 +-
 .../systemadministration/systemadministration.adoc |    4 +-
 .../workingwithapachesyncope/upgrade.adoc          |   14 +-
 src/main/resources/banner.txt                      |   22 +
 standalone/pom.xml                                 |    8 +-
 standalone/src/main/resources/context.xml          |   29 +
 standalone/src/main/resources/setenv.bat           |    2 +-
 standalone/src/main/resources/setenv.sh            |    2 +-
 342 files changed, 8034 insertions(+), 5765 deletions(-)

diff --git a/archetype/pom.xml b/archetype/pom.xml
index 69abfae..d9230a6 100644
--- a/archetype/pom.xml
+++ b/archetype/pom.xml
@@ -127,6 +127,13 @@ under the License.
       </resource>
 
       <resource>
+        <directory>../core/starter/src/main/resources</directory>
+        <includes>
+          <include>application.properties</include>
+        </includes>
+        <targetPath>${project.build.outputDirectory}/archetype-resources/core/src/main/resources</targetPath>
+      </resource>
+      <resource>
         <directory>../core/provisioning-java/src/main/resources</directory>
         <excludes>
           <exclude>*Context.xml</exclude>
@@ -136,8 +143,6 @@ under the License.
       <resource>
         <directory>../core/persistence-jpa/src/main/resources</directory>
         <excludes>
-          <exclude>*Context.xml</exclude>
-          <exclude>domains.xml</exclude>
           <exclude>META-INF/spring-persistence.xml</exclude>
         </excludes>
         <targetPath>${project.build.outputDirectory}/archetype-resources/core/src/main/resources</targetPath>
@@ -149,9 +154,6 @@ under the License.
       <resource>
         <directory>../core/logic/src/main/resources</directory>
         <targetPath>${project.build.outputDirectory}/archetype-resources/core/src/main/resources</targetPath>
-        <excludes>
-          <exclude>*Context.xml</exclude>
-        </excludes>
       </resource>
       <resource>
         <directory>../core/spring/src/main/resources</directory>
@@ -164,7 +166,7 @@ under the License.
         <directory>../fit/core-reference/src/main/resources</directory>
         <targetPath>${project.build.outputDirectory}/archetype-resources/core/src/main/resources</targetPath>
         <includes>
-          <include>coreContext.xml</include>
+          <include>application-embedded.properties</include>
           <include>log4j2.xml</include>
         </includes>
       </resource>
@@ -199,13 +201,6 @@ under the License.
         </includes>
       </resource>
       <resource>
-        <directory>../fit/core-reference/src/main/webapp</directory>
-        <targetPath>${project.build.outputDirectory}/archetype-resources/core/src/test/resources</targetPath>
-        <includes>
-          <include>*.jsp</include>
-        </includes>
-      </resource>
-      <resource>
         <directory>../fit/core-reference/src/main/webapp/WEB-INF</directory>
         <targetPath>${project.build.outputDirectory}/archetype-resources/core/src/main/webapp/WEB-INF</targetPath>
       </resource>
@@ -219,9 +214,10 @@ under the License.
       </resource>
             
       <resource>
-        <directory>../client/console/src/main/resources</directory>
+        <directory>../client/idrepo/console/src/main/resources</directory>
         <targetPath>${project.build.outputDirectory}/archetype-resources/console/src/main/resources</targetPath>
         <includes>
+          <include>application.properties</include>
           <include>console.properties</include>
         </includes>
       </resource>
@@ -243,6 +239,7 @@ under the License.
         <directory>../fit/console-reference/src/main/resources</directory>
         <targetPath>${project.build.outputDirectory}/archetype-resources/console/src/main/resources</targetPath>
         <includes>
+          <include>application-embedded.properties</include>
           <include>log4j2.xml</include>
         </includes>
       </resource>
@@ -271,6 +268,7 @@ under the License.
         <directory>../client/enduser/src/main/resources</directory>
         <targetPath>${project.build.outputDirectory}/archetype-resources/enduser/src/main/resources</targetPath>
         <includes>
+          <include>application.properties</include>
           <include>enduser.properties</include>
           <include>customFormAttributes.json</include>
           <include>customTemplate.json</include>
@@ -298,6 +296,7 @@ under the License.
         <directory>../fit/enduser-reference/src/main/resources</directory>
         <targetPath>${project.build.outputDirectory}/archetype-resources/enduser/src/main/resources</targetPath>
         <includes>
+          <include>application-embedded.properties</include>
           <include>log4j2.xml</include>
         </includes>
       </resource>
diff --git a/archetype/src/main/resources/archetype-resources/console/pom.xml b/archetype/src/main/resources/archetype-resources/console/pom.xml
index 822383c..7d2e04a 100644
--- a/archetype/src/main/resources/archetype-resources/console/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/console/pom.xml
@@ -33,68 +33,15 @@ under the License.
   <packaging>war</packaging>
 
   <dependencies>
-
-    <dependency> 
-      <groupId>javax.servlet</groupId> 
-      <artifactId>javax.servlet-api</artifactId> 
-    </dependency>
-    <dependency>
-      <groupId>javax.servlet.jsp</groupId>
-      <artifactId>javax.servlet.jsp-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>javax.servlet</groupId>
-      <artifactId>jstl</artifactId>
-    </dependency>
-
     <dependency>
       <groupId>${groupId}</groupId>
       <artifactId>syncope-common</artifactId>
       <version>${project.version}</version>
     </dependency>  
-    
+
     <dependency>
       <groupId>org.apache.syncope.client.idm</groupId>
       <artifactId>syncope-client-idm-console</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>
-    
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>jquery-ui</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>codemirror</artifactId>
     </dependency>    
   </dependencies>
 
@@ -165,5 +112,36 @@ under the License.
         </resources>
       </build>
     </profile>
+    
+    <profile>
+      <id>executable</id>
+      
+      <dependencies>
+        <dependency>
+          <groupId>org.springframework.boot</groupId>
+          <artifactId>spring-boot-starter-undertow</artifactId>
+        </dependency>
+      </dependencies>
+        
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-maven-plugin</artifactId>
+            <configuration>
+              <mainClass>org.apache.syncope.client.console.SyncopeConsoleApplication</mainClass>
+              <layout>ZIP</layout>
+            </configuration>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>repackage</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
   </profiles>
 </project>
diff --git a/archetype/src/main/resources/archetype-resources/core/pom.xml b/archetype/src/main/resources/archetype-resources/core/pom.xml
index c66cb51..994ddeb 100644
--- a/archetype/src/main/resources/archetype-resources/core/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/core/pom.xml
@@ -33,19 +33,6 @@ under the License.
   <packaging>war</packaging>
 
   <dependencies>
-    <dependency> 
-      <groupId>javax.servlet</groupId> 
-      <artifactId>javax.servlet-api</artifactId> 
-    </dependency>
-    <dependency>
-      <groupId>javax.servlet.jsp</groupId>
-      <artifactId>javax.servlet.jsp-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>javax.servlet</groupId>
-      <artifactId>jstl</artifactId>
-    </dependency>
-    
     <dependency>
       <groupId>${groupId}</groupId>
       <artifactId>syncope-common</artifactId>
@@ -53,59 +40,12 @@ under the License.
     </dependency>
     
     <dependency>
-      <groupId>org.apache.syncope.core.idm</groupId>
-      <artifactId>syncope-core-idm-rest-cxf</artifactId>
-    </dependency>
-    <dependency>
       <groupId>org.apache.syncope.core</groupId>
-      <artifactId>syncope-core-workflow-java</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.syncope.core</groupId>
-      <artifactId>syncope-core-persistence-jpa</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>
+      <artifactId>syncope-core-starter</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>
-    
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>jquery</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>jquery-ui</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars</groupId>
-      <artifactId>highlightjs</artifactId>
+      <groupId>org.apache.syncope.core.idm</groupId>
+      <artifactId>syncope-core-idm-rest-cxf</artifactId>
     </dependency>
   </dependencies>
 
@@ -160,7 +100,7 @@ under the License.
       
       <dependencies>
         <dependency>
-	  <groupId>org.apache.syncope.ext.flowable</groupId>
+          <groupId>org.apache.syncope.ext.flowable</groupId>
           <artifactId>syncope-ext-flowable-rest-cxf</artifactId>
           <version>${syncope.version}</version>
         </dependency>
@@ -238,6 +178,46 @@ under the License.
         </resources>
       </build>
     </profile>
+    
+    <profile>
+      <!--
+      This profile builds an executable war file.
+      In order for the app to run, it is necessary to include the conf directory and the JDBC driver in the runtime
+      classpath; according to official docs [1] this can be achieved by setting the LOADER_PATH env variable as follows:
+      
+      export LOADER_PATH=/path/to/conf/dir,/path/to/jdbc-driver.jar
+      
+      [1] https://docs.spring.io/spring-boot/docs/current/reference/html/executable-jar.html
+      -->
+      <id>executable</id>
+      
+      <dependencies>
+        <dependency>
+          <groupId>org.springframework.boot</groupId>
+          <artifactId>spring-boot-starter-undertow</artifactId>
+        </dependency>
+      </dependencies>
+        
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-maven-plugin</artifactId>
+            <configuration>
+              <mainClass>org.apache.syncope.core.starter.SyncopeCoreApplication</mainClass>
+              <layout>ZIP</layout>
+            </configuration>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>repackage</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
   </profiles>
 
 </project>
diff --git a/archetype/src/main/resources/archetype-resources/enduser/pom.xml b/archetype/src/main/resources/archetype-resources/enduser/pom.xml
index 1e3bb28..291d95a 100644
--- a/archetype/src/main/resources/archetype-resources/enduser/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/enduser/pom.xml
@@ -33,20 +33,6 @@ under the License.
   <packaging>war</packaging>
 
   <dependencies>
-
-    <dependency> 
-      <groupId>javax.servlet</groupId> 
-      <artifactId>javax.servlet-api</artifactId> 
-    </dependency>
-    <dependency>
-      <groupId>javax.servlet.jsp</groupId>
-      <artifactId>javax.servlet.jsp-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>javax.servlet</groupId>
-      <artifactId>jstl</artifactId>
-    </dependency>
-
     <dependency>
       <groupId>${groupId}</groupId>
       <artifactId>syncope-common</artifactId>
@@ -57,36 +43,6 @@ under the License.
       <groupId>org.apache.syncope.client</groupId>
       <artifactId>syncope-client-enduser</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>
   </dependencies>
 
   <build>
@@ -239,9 +195,6 @@ under the License.
                     <copy file="../core/target/test-classes/connid.properties" 
                           todir="../core/target/syncope/WEB-INF/classes" 
                           overwrite="true"/>
-                    <copy file="../core/target/test-classes/db.jsp" 
-                          todir="../core/target/syncope" 
-                          overwrite="true"/>
 
                     <copy file="${project.build.directory}/test-classes/enduser.properties" 
                           todir="${project.build.directory}/${project.build.finalName}/WEB-INF/classes" 
@@ -276,21 +229,27 @@ under the License.
             <inherited>true</inherited>
             <configuration>
               <container>
+                <containerId>tomcat9x</containerId>
+                <zipUrlInstaller>
+                  <url>http://central.maven.org/maven2/org/apache/tomcat/tomcat/${tomcat.version}/tomcat-${tomcat.version}.zip</url>
+                  <downloadDir>${settings.localRepository}/org/codehaus/cargo/cargo-container-archives</downloadDir>
+                  <extractDir>${project.build.directory}/cargo/extract</extractDir>
+                </zipUrlInstaller>
                 <dependencies>
                   <dependency>
                     <groupId>com.h2database</groupId>
                     <artifactId>h2</artifactId>
                   </dependency>
                 </dependencies>
+                <timeout>300000</timeout>
+                <log>${cargo.log}</log>
+                <output>${cargo.output}</output> 
               </container>
               <configuration>
-                <type>standalone</type>
                 <properties>
-                  <cargo.servlet.port>${cargo.servlet.port}</cargo.servlet.port>
-                  <cargo.tomcat.ajp.port>${cargo.tomcat.ajp.port}</cargo.tomcat.ajp.port>
-                  <cargo.rmi.port>${cargo.rmi.port}</cargo.rmi.port>
-
-                  <cargo.jvmargs>-noverify -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC</cargo.jvmargs>
+                  <cargo.jvmargs>
+                    -Dspring.profiles.active=embedded
+                    -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -Xmx1024m -Xms512m</cargo.jvmargs>
                 </properties>
               </configuration>
               <deployables>
@@ -380,5 +339,36 @@ under the License.
         </resources>
       </build>
     </profile>
+    
+    <profile>
+      <id>executable</id>
+      
+      <dependencies>
+        <dependency>
+          <groupId>org.springframework.boot</groupId>
+          <artifactId>spring-boot-starter-undertow</artifactId>
+        </dependency>
+      </dependencies>
+        
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-maven-plugin</artifactId>
+            <configuration>
+              <mainClass>org.apache.syncope.client.enduser.SyncopeEnduserApplication</mainClass>
+              <layout>ZIP</layout>
+            </configuration>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>repackage</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
   </profiles>
 </project>
diff --git a/archetype/src/main/resources/meta-pom.xml b/archetype/src/main/resources/meta-pom.xml
index c6193c8..4e38af7 100644
--- a/archetype/src/main/resources/meta-pom.xml
+++ b/archetype/src/main/resources/meta-pom.xml
@@ -55,18 +55,13 @@ under the License.
       </dependency>
       
       <dependency>
-        <groupId>org.apache.syncope.core.idm</groupId>
-        <artifactId>syncope-core-idm-rest-cxf</artifactId>
-        <version>${syncope.version}</version>
-      </dependency>
-      <dependency>
         <groupId>org.apache.syncope.core</groupId>
-        <artifactId>syncope-core-workflow-java</artifactId>
+        <artifactId>syncope-core-starter</artifactId>
         <version>${syncope.version}</version>
       </dependency>
       <dependency>
-        <groupId>org.apache.syncope.core</groupId>
-        <artifactId>syncope-core-persistence-jpa</artifactId>
+        <groupId>org.apache.syncope.core.idm</groupId>
+        <artifactId>syncope-core-idm-rest-cxf</artifactId>
         <version>${syncope.version}</version>
       </dependency>
         
diff --git a/client/enduser/pom.xml b/client/enduser/pom.xml
index 2038c24..481326d 100644
--- a/client/enduser/pom.xml
+++ b/client/enduser/pom.xml
@@ -45,8 +45,12 @@ under the License.
     </dependency>
 
     <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-context</artifactId>
+      <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>
@@ -181,11 +185,35 @@ under the License.
       <artifactId>jquery-ui</artifactId>
     </dependency>
 
-    <!--Logging-->
+    <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>
@@ -209,6 +237,14 @@ under the License.
         <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
index 207c789..c96da75 100644
--- 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
@@ -18,350 +18,44 @@
  */
 package org.apache.syncope.client.enduser;
 
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Serializable;
-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 com.giffing.wicket.spring.boot.starter.web.config.WicketWebInitializerAutoConfig.WebSocketWicketWebInitializerAutoConfiguration;
 import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.enduser.init.EnduserInitializer;
-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.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;
-
-public class SyncopeEnduserApplication extends WebApplication implements Serializable {
-
-    private static final long serialVersionUID = -6445919351044845120L;
-
-    private static final Logger LOG = LoggerFactory.getLogger(SyncopeEnduserApplication.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 SyncopeEnduserApplication get() {
-        return (SyncopeEnduserApplication) WebApplication.get();
+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);
     }
 
-    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").getLeft();
-
-        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
-        ClassPathScanImplementationLookup lookup = (ClassPathScanImplementationLookup) getServletContext().
-                getAttribute(EnduserInitializer.CLASSPATH_LOOKUP);
-        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();
-                }
-            });
-        }
+    protected SpringApplicationBuilder configure(final SpringApplicationBuilder builder) {
+        builder.properties(WebSocketWicketWebInitializerAutoConfiguration.REGISTER_SERVER_ENDPOINT_ENABLED + "=false");
+        return super.configure(builder);
     }
 
     @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 void addViewControllers(final ViewControllerRegistry registry) {
+        registry.addViewController("/app/").setViewName("forward:/app/index.html");
     }
 
-    public CustomTemplateInfo getCustomTemplate() {
-        return customTemplate;
+    @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
index 3b48522..1e7977b 100644
--- 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
@@ -74,10 +74,10 @@ public class SyncopeEnduserSession extends WebSession {
         // define cookie utility to manage application cookies
         cookieUtils = new CookieUtils();
 
-        anonymousClient = SyncopeEnduserApplication.get().getClientFactory().
+        anonymousClient = SyncopeWebApplication.get().getClientFactory().
                 create(new AnonymousAuthenticationHandler(
-                        SyncopeEnduserApplication.get().getAnonymousUser(),
-                        SyncopeEnduserApplication.get().getAnonymousKey()));
+                        SyncopeWebApplication.get().getAnonymousUser(),
+                        SyncopeWebApplication.get().getAnonymousKey()));
         platformInfo = anonymousClient.getService(SyncopeService.class).platform();
 
         datePlainSchemas = anonymousClient.getService(SchemaService.class).
@@ -106,8 +106,8 @@ public class SyncopeEnduserSession extends WebSession {
         boolean authenticated = false;
 
         try {
-            client = SyncopeEnduserApplication.get().getClientFactory().
-                    setDomain(SyncopeEnduserApplication.get().getDomain()).
+            client = SyncopeWebApplication.get().getClientFactory().
+                    setDomain(SyncopeWebApplication.get().getDomain()).
                     create(username, password);
 
             afterAuthentication(username);
@@ -124,8 +124,8 @@ public class SyncopeEnduserSession extends WebSession {
         boolean authenticated = false;
 
         try {
-            client = SyncopeEnduserApplication.get().getClientFactory().
-                    setDomain(SyncopeEnduserApplication.get().getDomain()).create(jwt);
+            client = SyncopeWebApplication.get().getClientFactory().
+                    setDomain(SyncopeWebApplication.get().getDomain()).create(jwt);
 
             afterAuthentication(null);
 
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/SyncopeWebApplication.java
similarity index 95%
copy from client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
copy to client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
index 207c789..f6ba9ad 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
@@ -20,10 +20,10 @@ 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.io.Serializable;
 import java.util.HashMap;
 import java.util.Map;
 import org.apache.syncope.client.enduser.pages.HomePage;
@@ -37,7 +37,6 @@ 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.init.EnduserInitializer;
 import org.apache.syncope.client.enduser.model.CustomAttributesInfo;
 import org.apache.syncope.client.enduser.model.CustomTemplateInfo;
 import org.apache.syncope.client.enduser.resources.CaptchaResource;
@@ -56,12 +55,13 @@ 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;
 
-public class SyncopeEnduserApplication extends WebApplication implements Serializable {
+@Component
+public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
 
-    private static final long serialVersionUID = -6445919351044845120L;
-
-    private static final Logger LOG = LoggerFactory.getLogger(SyncopeEnduserApplication.class);
+    private static final Logger LOG = LoggerFactory.getLogger(SyncopeWebApplication.class);
 
     private static final String ENDUSER_PROPERTIES = "enduser.properties";
 
@@ -69,10 +69,13 @@ public class SyncopeEnduserApplication extends WebApplication implements Seriali
 
     private static final String CUSTOM_TEMPLATE_FILE = "customTemplate.json";
 
-    public static SyncopeEnduserApplication get() {
-        return (SyncopeEnduserApplication) WebApplication.get();
+    public static SyncopeWebApplication get() {
+        return (SyncopeWebApplication) WebApplication.get();
     }
 
+    @Autowired
+    private ClassPathScanImplementationLookup lookup;
+
     private String domain;
 
     private String adminUser;
@@ -100,7 +103,7 @@ public class SyncopeEnduserApplication extends WebApplication implements Seriali
         super.init();
 
         // read enduser.properties
-        Properties props = PropertyUtils.read(getClass(), ENDUSER_PROPERTIES, "enduser.directory").getLeft();
+        Properties props = PropertyUtils.read(getClass(), ENDUSER_PROPERTIES, "enduser.directory");
 
         domain = props.getProperty("domain", SyncopeConstants.MASTER_DOMAIN);
         adminUser = props.getProperty("adminUser");
@@ -268,8 +271,6 @@ public class SyncopeEnduserApplication extends WebApplication implements Seriali
         }
 
         // mount resources
-        ClassPathScanImplementationLookup lookup = (ClassPathScanImplementationLookup) getServletContext().
-                getAttribute(EnduserInitializer.CLASSPATH_LOOKUP);
         for (Class<? extends AbstractResource> resource : lookup.getResources()) {
             Resource annotation = resource.getAnnotation(Resource.class);
             if (annotation == null) {
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
index e194d6b..4f60fc9 100644
--- 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
@@ -19,7 +19,7 @@
 package org.apache.syncope.client.enduser.adapters;
 
 import java.util.Map;
-import org.apache.syncope.client.enduser.SyncopeEnduserApplication;
+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;
@@ -33,9 +33,9 @@ public final class PlatformInfoAdapter {
         request.setSelfRegAllowed(platformInfo.isSelfRegAllowed());
         request.setPwdResetRequiringSecurityQuestions(platformInfo.isPwdResetRequiringSecurityQuestions());
         request.setVersion(platformInfo.getVersion());
-        request.setCaptchaEnabled(SyncopeEnduserApplication.get().isCaptchaEnabled());
-        if (SyncopeEnduserApplication.get().getMaxUploadFileSizeMB() != null) {
-            request.setMaxUploadFileSizeMB(SyncopeEnduserApplication.get().getMaxUploadFileSizeMB());
+        request.setCaptchaEnabled(SyncopeWebApplication.get().isCaptchaEnabled());
+        if (SyncopeWebApplication.get().getMaxUploadFileSizeMB() != null) {
+            request.setMaxUploadFileSizeMB(SyncopeWebApplication.get().getMaxUploadFileSizeMB());
         }
         request.setCustomFormAttributes(customFormAttributes);
 
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/init/EnduserInitializer.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/init/EnduserInitializer.java
deleted file mode 100644
index 6295cd2..0000000
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/init/EnduserInitializer.java
+++ /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.
- */
-package org.apache.syncope.client.enduser.init;
-
-import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-import javax.servlet.annotation.WebListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Take care of all initializations needed by Syncope Enduser to run up and safe.
- */
-@WebListener
-public class EnduserInitializer implements ServletContextListener {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EnduserInitializer.class);
-
-    public static final String CLASSPATH_LOOKUP = "CLASSPATH_LOOKUP";
-
-    @Override
-    public void contextInitialized(final ServletContextEvent sce) {
-        ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup();
-        lookup.load();
-        sce.getServletContext().setAttribute(CLASSPATH_LOOKUP, lookup);
-
-        LOG.debug("Initialization completed");
-    }
-
-    @Override
-    public void contextDestroyed(final ServletContextEvent sce) {
-        // nothing to do
-    }
-
-}
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
index 9e7ebb5..c948778 100644
--- 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
@@ -22,7 +22,7 @@ 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.SyncopeEnduserApplication;
+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;
@@ -40,7 +40,7 @@ public abstract class BaseResource extends AbstractResource {
 
     protected final boolean xsrfCheck(final HttpServletRequest request) {
         final String requestXSRFHeader = request.getHeader(SyncopeEnduserConstants.XSRF_HEADER_NAME);
-        return SyncopeEnduserApplication.get().isXsrfEnabled()
+        return SyncopeWebApplication.get().isXsrfEnabled()
                 ? StringUtils.isNotBlank(requestXSRFHeader)
                 && SyncopeEnduserSession.get().getCookieUtils().
                         getCookie(SyncopeEnduserConstants.XSRF_COOKIE).getValue().equals(requestXSRFHeader)
@@ -48,7 +48,7 @@ public abstract class BaseResource extends AbstractResource {
     }
 
     protected final boolean captchaCheck(final String enteredCaptcha, final Object currentCaptcha) {
-        return SyncopeEnduserApplication.get().isCaptchaEnabled()
+        return SyncopeWebApplication.get().isCaptchaEnabled()
                 ? StringUtils.isBlank(currentCaptcha.toString()) || enteredCaptcha == null
                 ? false
                 : enteredCaptcha.equals(currentCaptcha.toString())
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
index 86b19bd..ec62a08 100644
--- 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
@@ -25,7 +25,7 @@ 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.SyncopeEnduserApplication;
+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;
@@ -60,7 +60,7 @@ public class DynamicTemplateResource extends BaseResource {
 
                 @Override
                 public void writeData(final IResource.Attributes attributes) throws IOException {
-                    CustomTemplateInfo customTemplate = SyncopeEnduserApplication.get().getCustomTemplate();
+                    CustomTemplateInfo customTemplate = SyncopeWebApplication.get().getCustomTemplate();
                     attributes.getResponse().write(MAPPER.writeValueAsString(customTemplate));
                 }
             });
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
index 2d7736c..e495816 100644
--- 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
@@ -25,7 +25,7 @@ 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.SyncopeEnduserApplication;
+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;
@@ -53,7 +53,7 @@ public class ExternalResourceResource extends BaseResource {
             }
 
             CustomTemplateInfo customTemplate =
-                    SyncopeEnduserApplication.get().getCustomTemplate();
+                    SyncopeWebApplication.get().getCustomTemplate();
             final List<String> resources = customTemplate.getWizard().getSteps().containsKey("groups")
                     ? SyncopeEnduserSession.get().
                             getService(SyncopeService.class).platform().getResources()
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
index d2b7a20..9001913 100644
--- 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
@@ -29,7 +29,7 @@ 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.SyncopeEnduserApplication;
+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;
@@ -59,7 +59,7 @@ public class GroupResource extends BaseResource {
             }
 
             CustomTemplateInfo customTemplate =
-                    SyncopeEnduserApplication.get().getCustomTemplate();
+                    SyncopeWebApplication.get().getCustomTemplate();
             final GroupResponse groupResponse = new GroupResponse();
             if (customTemplate.getWizard().getSteps().containsKey("groups")) {
                 String realm = URLDecoder.decode(attributes.getParameters().get("realm").
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
index 9b990a0..12bd30f 100644
--- 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
@@ -25,7 +25,7 @@ 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.SyncopeEnduserApplication;
+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;
@@ -63,7 +63,7 @@ public class InfoResource extends BaseResource {
                 @Override
                 public void writeData(final IResource.Attributes attributes) throws IOException {
                     Map<String, CustomAttributesInfo> customFormAttributes =
-                            SyncopeEnduserApplication.get().getCustomFormAttributes();
+                            SyncopeWebApplication.get().getCustomFormAttributes();
                     attributes.getResponse().write(
                             MAPPER.writeValueAsString(
                                     PlatformInfoAdapter.toPlatformInfoRequest(
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
index b3bf91d..8e4086e 100644
--- 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
@@ -24,7 +24,7 @@ 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.SyncopeEnduserApplication;
+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;
@@ -61,7 +61,7 @@ public class LoginResource extends BaseResource {
                 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 (!SyncopeEnduserApplication.get().getAdminUser().equalsIgnoreCase(username)
+            } else if (!SyncopeWebApplication.get().getAdminUser().equalsIgnoreCase(username)
                     && SyncopeEnduserSession.get().authenticate(username, password)) {
                 // user has been authenticated successfully
                 response.setTextEncoding(StandardCharsets.UTF_8.name());
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
index b6c57e8..8ebee91 100644
--- 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
@@ -29,7 +29,7 @@ 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.SyncopeEnduserApplication;
+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;
@@ -90,9 +90,9 @@ public class SchemaResource extends BaseResource {
 
             // USER from customization, if empty or null ignore it, use it to filter attributes otherwise
             Map<String, CustomAttributesInfo> customFormAttributes =
-                    SyncopeEnduserApplication.get().getCustomFormAttributes();
+                    SyncopeWebApplication.get().getCustomFormAttributes();
             CustomTemplateInfo customTemplate =
-                    SyncopeEnduserApplication.get().getCustomTemplate();
+                    SyncopeWebApplication.get().getCustomTemplate();
 
             SchemaService schemaService = SyncopeEnduserSession.get().getService(SchemaService.class);
             final List<SchemaTO> plainSchemas = classes.isEmpty()
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
index a2d1339..4e8aea6 100644
--- 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
@@ -24,7 +24,7 @@ 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.SyncopeEnduserApplication;
+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;
@@ -83,7 +83,7 @@ public class UserSelfCreateResource extends BaseUserSelfResource {
 
                 // check if request is compliant with customization form rules
                 if (Validation.isCompliant(userTO,
-                        SyncopeEnduserApplication.get().getCustomFormAttributes(), true)) {
+                        SyncopeWebApplication.get().getCustomFormAttributes(), true)) {
 
                     // 1. membership attributes management
                     Set<Attr> membAttrs = new HashSet<>();
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
index d0a5658..3425ca0 100644
--- 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
@@ -27,7 +27,7 @@ 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.SyncopeEnduserApplication;
+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;
@@ -97,7 +97,7 @@ public class UserSelfReadResource extends BaseUserSelfResource {
                 membership.getVirAttrs().clear();
             }
             // USER from customization, if empty or null ignore it, use it to filter attributes otherwise
-            applyFromCustomization(userTO, SyncopeEnduserApplication.get().getCustomFormAttributes());
+            applyFromCustomization(userTO, SyncopeWebApplication.get().getCustomFormAttributes());
 
             // 1.1 Date -> millis conversion for PLAIN attributes of USER
             for (PlainSchemaTO plainSchema : SyncopeEnduserSession.get().getDatePlainSchemas()) {
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
index 12a5143..897cb25 100644
--- 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
@@ -25,7 +25,7 @@ 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.SyncopeEnduserApplication;
+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;
@@ -67,7 +67,7 @@ public class UserSelfUpdateResource extends BaseUserSelfResource {
 
             UserTO userTO = MAPPER.readValue(request.getReader().readLine(), UserTO.class);
             Map<String, CustomAttributesInfo> customFormAttributes =
-                    SyncopeEnduserApplication.get().getCustomFormAttributes();
+                    SyncopeWebApplication.get().getCustomFormAttributes();
 
             // check if request is compliant with customization form rules
             if (Validation.isCompliant(userTO, customFormAttributes, false)) {
diff --git a/client/enduser/src/main/resources/META-INF/web-fragment.xml b/client/enduser/src/main/resources/META-INF/web-fragment.xml
deleted file mode 100644
index d33e0f6..0000000
--- a/client/enduser/src/main/resources/META-INF/web-fragment.xml
+++ /dev/null
@@ -1,46 +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.
--->
-<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee"
-              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
-                                  http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
-              id="${pom.artifactId}" version="3.1">
-  
-  <filter>
-    <filter-name>SyncopeEnduser</filter-name>
-    <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
-    <init-param>
-      <param-name>applicationClassName</param-name>
-      <param-value>org.apache.syncope.client.enduser.SyncopeEnduserApplication</param-value>
-    </init-param>
-    <init-param>
-      <param-name>filterMappingUrlPattern</param-name>
-      <param-value>/*</param-value>
-    </init-param>
-  </filter>
-  
-  <filter-mapping>
-    <filter-name>SyncopeEnduser</filter-name>
-    <url-pattern>/*</url-pattern>
-    <dispatcher>REQUEST</dispatcher>
-    <dispatcher>INCLUDE</dispatcher>
-  </filter-mapping>
-  
-</web-fragment>
diff --git a/core/persistence-jpa/src/test/resources/domains/Two.properties b/client/enduser/src/main/resources/application.properties
similarity index 72%
copy from core/persistence-jpa/src/test/resources/domains/Two.properties
copy to client/enduser/src/main/resources/application.properties
index ea19bd7..dfd8b8d 100644
--- a/core/persistence-jpa/src/test/resources/domains/Two.properties
+++ b/client/enduser/src/main/resources/application.properties
@@ -14,15 +14,12 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-Two.driverClassName=org.h2.Driver
-Two.url=jdbc:h2:file:${conf.directory}/syncopetwo.db
-Two.schema=
-Two.username=sa
-Two.password=
-Two.databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary
-Two.orm=META-INF/spring-orm.xml
+spring.application.name=Apache Syncope ${syncope.version} Enduser
+spring.groovy.template.check-template-location=false
+spring.main.banner-mode=log
 
-Two.pool.maxActive=10
-Two.pool.minIdle=2
+spring.http.encoding.charset=UTF-8
+spring.http.encoding.enabled=true
+spring.http.encoding.force=true
 
-Two.audit.sql=audit.sql
+server.servlet.contextPath=/syncope-enduser
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAditionalActionLinksProvider.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAditionalActionLinksProvider.java
index 45bec8b..55414fd 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAditionalActionLinksProvider.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAditionalActionLinksProvider.java
@@ -39,6 +39,8 @@ import org.apache.wicket.model.Model;
 public class IdMAnyDirectoryPanelAditionalActionLinksProvider
         implements AnyDirectoryPanelAditionalActionLinksProvider {
 
+    private static final long serialVersionUID = -1698293704237878993L;
+
     @Override
     public List<Action<UserTO>> get(
             final UserTO modelObject,
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMExternalResourceProvider.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMExternalResourceProvider.java
index dcfb43e..407aafb 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMExternalResourceProvider.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMExternalResourceProvider.java
@@ -25,6 +25,8 @@ import org.apache.syncope.common.lib.to.EntityTO;
 
 public class IdMExternalResourceProvider implements ExternalResourceProvider {
 
+    private static final long serialVersionUID = 6335503820405008093L;
+
     @Override
     public List<String> get() {
         return new ResourceRestClient().list().stream().map(EntityTO::getKey).collect(Collectors.toList());
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMStatusProvider.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMStatusProvider.java
index 2b8b303..8c43cae 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMStatusProvider.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMStatusProvider.java
@@ -30,6 +30,8 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 
 public class IdMStatusProvider implements StatusProvider {
 
+    private static final long serialVersionUID = 1875374599950896631L;
+
     @Override
     public List<Triple<ConnObjectTO, ConnObjectWrapper, String>> get(
             final AnyTO any, final Collection<String> resources) {
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMVirSchemaDetailsPanelProvider.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMVirSchemaDetailsPanelProvider.java
index 87f0a72..ecc0605 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMVirSchemaDetailsPanelProvider.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMVirSchemaDetailsPanelProvider.java
@@ -24,6 +24,8 @@ import org.apache.wicket.markup.html.panel.Panel;
 
 public class IdMVirSchemaDetailsPanelProvider implements VirSchemaDetailsPanelProvider {
 
+    private static final long serialVersionUID = -173141337550903982L;
+
     @Override
     public Panel get(final String id, final VirSchemaTO schemaTO) {
         return new VirSchemaDetails("details", schemaTO);
diff --git a/client/idrepo/console/pom.xml b/client/idrepo/console/pom.xml
index e02b4e1..8eee0c2 100644
--- a/client/idrepo/console/pom.xml
+++ b/client/idrepo/console/pom.xml
@@ -45,8 +45,12 @@ under the License.
     </dependency>
 
     <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-context</artifactId>
+      <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>
@@ -147,11 +151,36 @@ under the License.
       <groupId>org.webjars</groupId>
       <artifactId>jQuery-slimScroll</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>
   </dependencies>
   
   <build>
@@ -181,7 +210,15 @@ under the License.
           <include>**/*.woff2</include>
         </includes>
       </resource>
-      
+
+      <resource>
+        <directory>${basedir}/../../../src/main/resources</directory>
+        <filtering>true</filtering>
+        <includes>
+          <include>banner.txt</include>
+        </includes>
+      </resource>
+
       <resource>
         <directory>${basedir}</directory>
         <targetPath>META-INF</targetPath>
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/BookmarkablePageLinkBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/BookmarkablePageLinkBuilder.java
index fe87a88..14d1d0c 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/BookmarkablePageLinkBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/BookmarkablePageLinkBuilder.java
@@ -33,7 +33,7 @@ public final class BookmarkablePageLinkBuilder {
             final String key, final String id, final Class<T> defaultPageClass) {
 
         @SuppressWarnings("unchecked")
-        Class<T> pageClass = (Class<T>) SyncopeConsoleApplication.get().getPageClass(key);
+        Class<T> pageClass = (Class<T>) SyncopeWebApplication.get().getPageClass(key);
         return new BookmarkablePageLink<>(
                 id,
                 pageClass == null ? defaultPageClass : pageClass);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
index 8760c1e..ee78fc7 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
@@ -18,343 +18,45 @@
  */
 package org.apache.syncope.client.console;
 
-import de.agilecoders.wicket.core.Bootstrap;
-import de.agilecoders.wicket.core.settings.BootstrapSettings;
-import de.agilecoders.wicket.core.settings.IBootstrapSettings;
-import de.agilecoders.wicket.core.settings.SingleThemeProvider;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Properties;
-import java.util.stream.Collectors;
-import org.apache.commons.collections4.ListUtils;
-import org.apache.commons.lang3.BooleanUtils;
-import org.apache.commons.lang3.ClassUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.annotations.Resource;
-import org.apache.syncope.client.console.commons.AnyDirectoryPanelAditionalActionLinksProvider;
-import org.apache.syncope.client.console.commons.AnyWizardBuilderAdditionalSteps;
-import org.apache.syncope.client.console.commons.Constants;
+import com.giffing.wicket.spring.boot.starter.web.config.WicketWebInitializerAutoConfig.WebSocketWicketWebInitializerAutoConfiguration;
 import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.console.init.ConsoleInitializer;
-import org.apache.syncope.client.console.pages.BasePage;
-import org.apache.syncope.client.console.pages.Dashboard;
-import org.apache.syncope.client.console.pages.MustChangePassword;
-import org.apache.syncope.client.console.pages.Login;
-import org.apache.syncope.client.console.themes.AdminLTE;
-import org.apache.syncope.client.lib.AnonymousAuthenticationHandler;
-import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
-import org.apache.syncope.common.lib.PropertyUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.EntityTO;
-import org.apache.syncope.common.rest.api.service.DomainService;
-import org.apache.wicket.Page;
-import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession;
-import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication;
-import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.markup.html.WebPage;
-import org.apache.wicket.protocol.http.CsrfPreventionRequestCycleListener;
-import org.apache.wicket.protocol.http.WebApplication;
-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.resource.JQueryResourceReference;
-import org.apache.wicket.util.lang.Args;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.syncope.client.console.commons.ExternalResourceProvider;
-import org.apache.syncope.client.console.commons.StatusProvider;
-import org.apache.syncope.client.console.commons.VirSchemaDetailsPanelProvider;
-
-public class SyncopeConsoleApplication extends AuthenticatedWebApplication {
-
-    private static final Logger LOG = LoggerFactory.getLogger(SyncopeConsoleApplication.class);
-
-    private static final String CONSOLE_PROPERTIES = "console.properties";
-
-    public static final List<Locale> SUPPORTED_LOCALES = Collections.unmodifiableList(Arrays.asList(
-            new Locale[] {
-                Locale.ENGLISH, Locale.ITALIAN, new Locale("pt", "BR"), new Locale("ru"), Locale.JAPANESE
-            }));
-
-    public static SyncopeConsoleApplication get() {
-        return (SyncopeConsoleApplication) WebApplication.get();
-    }
-
-    private String site;
-
-    private String anonymousUser;
-
-    private String anonymousKey;
-
-    private String reconciliationReportKey;
-
-    private String scheme;
-
-    private String host;
-
-    private String port;
-
-    private String rootPath;
-
-    private String useGZIPCompression;
-
-    private Integer maxUploadFileSizeMB;
-
-    private Integer maxWaitTime;
-
-    private Integer corePoolSize;
-
-    private Integer maxPoolSize;
-
-    private Integer queueCapacity;
-
-    private List<String> domains;
-
-    private ExternalResourceProvider resourceProvider;
-
-    private AnyWizardBuilderAdditionalSteps anyWizardBuilderAdditionalSteps;
-
-    private StatusProvider statusProvider;
-
-    private VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider;
-
-    private AnyDirectoryPanelAditionalActionLinksProvider anyDirectoryPanelAditionalActionLinksProvider;
-
-    private Map<String, Class<? extends BasePage>> pageClasses;
-
-    @SuppressWarnings("unchecked")
-    protected void populatePageClasses(final Properties props) {
-        Enumeration<String> propNames = (Enumeration<String>) props.propertyNames();
-        while (propNames.hasMoreElements()) {
-            String name = propNames.nextElement();
-            if (name.startsWith("page.")) {
-                try {
-                    Class<?> clazz = ClassUtils.getClass(props.getProperty(name));
-                    if (BasePage.class.isAssignableFrom(clazz)) {
-                        pageClasses.put(
-                                StringUtils.substringAfter("page.", name), (Class<? extends BasePage>) clazz);
-                    } else {
-                        LOG.warn("{} does not extend {}, ignoring...", clazz.getName(), BasePage.class.getName());
-                    }
-                } catch (ClassNotFoundException e) {
-                    LOG.error("While looking for class identified by property '{}'", name, e);
-                }
-            }
-        }
+import org.apache.syncope.client.console.init.MIMETypesLoader;
+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;
+
+@SpringBootApplication
+@EnableAutoConfiguration(exclude = {
+    ErrorMvcAutoConfiguration.class,
+    HttpMessageConvertersAutoConfiguration.class })
+public class SyncopeConsoleApplication extends SpringBootServletInitializer {
+
+    public static void main(final String[] args) {
+        SpringApplication.run(SyncopeConsoleApplication.class, args);
     }
 
     @Override
-    protected void init() {
-        super.init();
-
-        // read console.properties
-        Properties props = PropertyUtils.read(getClass(), CONSOLE_PROPERTIES, "console.directory").getLeft();
-
-        site = props.getProperty("site");
-        Args.notNull(site, "<site>");
-        anonymousUser = props.getProperty("anonymousUser");
-        Args.notNull(anonymousUser, "<anonymousUser>");
-        anonymousKey = props.getProperty("anonymousKey");
-        Args.notNull(anonymousKey, "<anonymousKey>");
-
-        scheme = props.getProperty("scheme");
-        Args.notNull(scheme, "<scheme>");
-        host = props.getProperty("host");
-        Args.notNull(host, "<host>");
-        port = props.getProperty("port");
-        Args.notNull(port, "<port>");
-        rootPath = props.getProperty("rootPath");
-        Args.notNull(rootPath, "<rootPath>");
-        useGZIPCompression = props.getProperty("useGZIPCompression");
-        Args.notNull(useGZIPCompression, "<useGZIPCompression>");
-        maxUploadFileSizeMB = props.getProperty("maxUploadFileSizeMB") == null
-                ? null
-                : Integer.valueOf(props.getProperty("maxUploadFileSizeMB"));
-
-        maxWaitTime = Integer.valueOf(props.getProperty("maxWaitTimeOnApplyChanges", "30"));
-
-        // Resource connections check thread pool size
-        corePoolSize = Integer.valueOf(props.getProperty("executor.corePoolSize", "5"));
-        maxPoolSize = Integer.valueOf(props.getProperty("executor.maxPoolSize", "10"));
-        queueCapacity = Integer.valueOf(props.getProperty("executor.queueCapacity", "50"));
-
-        String csrf = props.getProperty("csrf");
-
-        // process page properties
-        pageClasses = new HashMap<>();
-        populatePageClasses(props);
-        pageClasses = Collections.unmodifiableMap(pageClasses);
-
-        // Application settings
-        IBootstrapSettings settings = new BootstrapSettings();
-
-        // set theme provider
-        settings.setThemeProvider(new SingleThemeProvider(new AdminLTE()));
-
-        // install application settings
-        Bootstrap.install(this, settings);
-
-        getResourceSettings().setUseMinifiedResources(true);
-
-        getResourceSettings().setThrowExceptionOnMissingResource(true);
-
-        getJavaScriptLibrarySettings().setJQueryReference(JQueryResourceReference.getV2());
-
-        getSecuritySettings().setAuthorizationStrategy(new MetaDataRoleAuthorizationStrategy(this));
-
-        ClassPathScanImplementationLookup lookup = (ClassPathScanImplementationLookup) getServletContext().
-                getAttribute(ConsoleInitializer.CLASSPATH_LOOKUP);
-        resourceProvider = lookup.getResourceProvider();
-        anyWizardBuilderAdditionalSteps = lookup.getAnyWizardBuilderAdditionalSteps();
-        statusProvider = lookup.getStatusProvider();
-        virSchemaDetailsPanelProvider = lookup.getVirSchemaDetailsPanelProvider();
-        anyDirectoryPanelAditionalActionLinksProvider = lookup.getAnyDirectoryPanelAditionalActionLinksProvider();
-        lookup.getPageClasses().
-                forEach(cls -> MetaDataRoleAuthorizationStrategy.authorize(cls, Constants.ROLE_AUTHENTICATED));
-
-        getMarkupSettings().setStripWicketTags(true);
-        getMarkupSettings().setCompressWhitespace(true);
-
-        if (BooleanUtils.toBoolean(csrf)) {
-            getRequestCycleListeners().add(new CsrfPreventionRequestCycleListener());
-        }
-        getRequestCycleListeners().add(new SyncopeConsoleRequestCycleListener());
-
-        mountPage("/login", getSignInPageClass());
-
-        try {
-            reconciliationReportKey = props.getProperty("reconciliationReportKey");
-        } catch (NumberFormatException e) {
-            LOG.error("While parsing reconciliationReportKey", e);
-        }
-        Args.notNull(reconciliationReportKey, "<reconciliationReportKey>");
-
-        for (Class<? extends AbstractResource> resource : lookup.getResources()) {
-            Resource annotation = resource.getAnnotation(Resource.class);
-            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);
-            }
-        }
-
-        // enable component path
-        if (getDebugSettings().isAjaxDebugModeEnabled()) {
-            getDebugSettings().setComponentPathAttributeName("syncope-path");
-        }
-    }
-
-    @Override
-    protected Class<? extends AbstractAuthenticatedWebSession> getWebSessionClass() {
-        return SyncopeConsoleSession.class;
-    }
-
-    @Override
-    protected Class<? extends WebPage> getSignInPageClass() {
-        return Login.class;
-    }
-
-    @Override
-    public Class<? extends Page> getHomePage() {
-        return AuthenticatedWebSession.get().isSignedIn()
-                && SyncopeConsoleSession.get().getSelfTO().isMustChangePassword()
-                ? MustChangePassword.class
-                : Dashboard.class;
-    }
-
-    public Class<? extends BasePage> getPageClass(final String key) {
-        return pageClasses.get(key);
-    }
-
-    public String getSite() {
-        return site;
-    }
-
-    public String getAnonymousUser() {
-        return anonymousUser;
-    }
-
-    public String getAnonymousKey() {
-        return anonymousKey;
-    }
-
-    public String getReconciliationReportKey() {
-        return reconciliationReportKey;
-    }
-
-    public Integer getMaxUploadFileSizeMB() {
-        return maxUploadFileSizeMB;
-    }
-
-    public Integer getMaxWaitTimeInSeconds() {
-        return maxWaitTime;
-    }
-
-    public Integer getCorePoolSize() {
-        return corePoolSize;
-    }
-
-    public Integer getMaxPoolSize() {
-        return maxPoolSize;
-    }
-
-    public Integer getQueueCapacity() {
-        return queueCapacity;
-    }
-
-    public SyncopeClientFactoryBean newClientFactory() {
-        return new SyncopeClientFactoryBean().
-                setAddress(scheme + "://" + host + ":" + port + StringUtils.prependIfMissing(rootPath, "/")).
-                setUseCompression(BooleanUtils.toBoolean(useGZIPCompression));
-    }
-
-    public List<String> getDomains() {
-        synchronized (LOG) {
-            if (domains == null) {
-                domains = newClientFactory().create(
-                        new AnonymousAuthenticationHandler(anonymousUser, anonymousKey)).
-                        getService(DomainService.class).list().stream().map(EntityTO::getKey).
-                        collect(Collectors.toList());
-                domains.add(0, SyncopeConstants.MASTER_DOMAIN);
-                domains = ListUtils.unmodifiableList(domains);
-            }
-        }
-        return domains;
-    }
-
-    public ExternalResourceProvider getResourceProvider() {
-        return resourceProvider;
-    }
-
-    public AnyWizardBuilderAdditionalSteps getAnyWizardBuilderAdditionalSteps() {
-        return anyWizardBuilderAdditionalSteps;
-    }
-
-    public StatusProvider getStatusProvider() {
-        return statusProvider;
+    protected SpringApplicationBuilder configure(final SpringApplicationBuilder builder) {
+        builder.properties(WebSocketWicketWebInitializerAutoConfiguration.REGISTER_SERVER_ENDPOINT_ENABLED + "=false");
+        return super.configure(builder);
     }
 
-    public VirSchemaDetailsPanelProvider getVirSchemaDetailsPanelProvider() {
-        return virSchemaDetailsPanelProvider;
+    @Bean
+    public ClassPathScanImplementationLookup classPathScanImplementationLookup() {
+        ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup();
+        lookup.load();
+        return lookup;
     }
 
-    public AnyDirectoryPanelAditionalActionLinksProvider getAnyDirectoryPanelAditionalActionLinksProvider() {
-        return anyDirectoryPanelAditionalActionLinksProvider;
+    @Bean
+    public MIMETypesLoader mimeTypesLoader() {
+        MIMETypesLoader mimeTypesLoader = new MIMETypesLoader();
+        mimeTypesLoader.load();
+        return mimeTypesLoader;
     }
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
index 324b9ea..7aad674 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
@@ -94,20 +94,20 @@ public class SyncopeConsoleSession extends AuthenticatedWebSession {
     public SyncopeConsoleSession(final Request request) {
         super(request);
 
-        clientFactory = SyncopeConsoleApplication.get().newClientFactory();
+        clientFactory = SyncopeWebApplication.get().newClientFactory();
         anonymousClient = clientFactory.
                 create(new AnonymousAuthenticationHandler(
-                        SyncopeConsoleApplication.get().getAnonymousUser(),
-                        SyncopeConsoleApplication.get().getAnonymousKey()));
+                        SyncopeWebApplication.get().getAnonymousUser(),
+                        SyncopeWebApplication.get().getAnonymousKey()));
 
         platformInfo = anonymousClient.getService(SyncopeService.class).platform();
         systemInfo = anonymousClient.getService(SyncopeService.class).system();
 
         executor = new ThreadPoolTaskExecutor();
         executor.setWaitForTasksToCompleteOnShutdown(false);
-        executor.setCorePoolSize(SyncopeConsoleApplication.get().getCorePoolSize());
-        executor.setMaxPoolSize(SyncopeConsoleApplication.get().getMaxPoolSize());
-        executor.setQueueCapacity(SyncopeConsoleApplication.get().getQueueCapacity());
+        executor.setCorePoolSize(SyncopeWebApplication.get().getCorePoolSize());
+        executor.setMaxPoolSize(SyncopeWebApplication.get().getMaxPoolSize());
+        executor.setQueueCapacity(SyncopeWebApplication.get().getQueueCapacity());
         executor.initialize();
     }
 
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java
similarity index 95%
copy from client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
copy to client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java
index 8760c1e..e59aa76 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console;
 
+import com.giffing.wicket.spring.boot.starter.app.WicketBootSecuredWebApplication;
 import de.agilecoders.wicket.core.Bootstrap;
 import de.agilecoders.wicket.core.settings.BootstrapSettings;
 import de.agilecoders.wicket.core.settings.IBootstrapSettings;
@@ -40,7 +41,6 @@ import org.apache.syncope.client.console.commons.AnyDirectoryPanelAditionalActio
 import org.apache.syncope.client.console.commons.AnyWizardBuilderAdditionalSteps;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.console.init.ConsoleInitializer;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.pages.Dashboard;
 import org.apache.syncope.client.console.pages.MustChangePassword;
@@ -54,7 +54,6 @@ import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.rest.api.service.DomainService;
 import org.apache.wicket.Page;
 import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession;
-import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication;
 import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
 import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
 import org.apache.wicket.markup.html.WebPage;
@@ -70,10 +69,13 @@ import org.slf4j.LoggerFactory;
 import org.apache.syncope.client.console.commons.ExternalResourceProvider;
 import org.apache.syncope.client.console.commons.StatusProvider;
 import org.apache.syncope.client.console.commons.VirSchemaDetailsPanelProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 
-public class SyncopeConsoleApplication extends AuthenticatedWebApplication {
+@Component
+public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
 
-    private static final Logger LOG = LoggerFactory.getLogger(SyncopeConsoleApplication.class);
+    private static final Logger LOG = LoggerFactory.getLogger(SyncopeWebApplication.class);
 
     private static final String CONSOLE_PROPERTIES = "console.properties";
 
@@ -82,10 +84,13 @@ public class SyncopeConsoleApplication extends AuthenticatedWebApplication {
                 Locale.ENGLISH, Locale.ITALIAN, new Locale("pt", "BR"), new Locale("ru"), Locale.JAPANESE
             }));
 
-    public static SyncopeConsoleApplication get() {
-        return (SyncopeConsoleApplication) WebApplication.get();
+    public static SyncopeWebApplication get() {
+        return (SyncopeWebApplication) WebApplication.get();
     }
 
+    @Autowired
+    private ClassPathScanImplementationLookup lookup;
+
     private String site;
 
     private String anonymousUser;
@@ -154,7 +159,7 @@ public class SyncopeConsoleApplication extends AuthenticatedWebApplication {
         super.init();
 
         // read console.properties
-        Properties props = PropertyUtils.read(getClass(), CONSOLE_PROPERTIES, "console.directory").getLeft();
+        Properties props = PropertyUtils.read(getClass(), CONSOLE_PROPERTIES, "console.directory");
 
         site = props.getProperty("site");
         Args.notNull(site, "<site>");
@@ -208,8 +213,6 @@ public class SyncopeConsoleApplication extends AuthenticatedWebApplication {
 
         getSecuritySettings().setAuthorizationStrategy(new MetaDataRoleAuthorizationStrategy(this));
 
-        ClassPathScanImplementationLookup lookup = (ClassPathScanImplementationLookup) getServletContext().
-                getAttribute(ConsoleInitializer.CLASSPATH_LOOKUP);
         resourceProvider = lookup.getResourceProvider();
         anyWizardBuilderAdditionalSteps = lookup.getAnyWizardBuilderAdditionalSteps();
         statusProvider = lookup.getStatusProvider();
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/AnyDirectoryPanelAditionalActionLinksProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/AnyDirectoryPanelAditionalActionLinksProvider.java
index a9307dc..b56fecc 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/AnyDirectoryPanelAditionalActionLinksProvider.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/AnyDirectoryPanelAditionalActionLinksProvider.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.commons;
 
+import java.io.Serializable;
 import java.util.List;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.Action;
@@ -27,7 +28,7 @@ import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.wicket.PageReference;
 
-public interface AnyDirectoryPanelAditionalActionLinksProvider {
+public interface AnyDirectoryPanelAditionalActionLinksProvider extends Serializable {
 
     List<Action<UserTO>> get(
             UserTO modelObject,
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyAnyDirectoryPanelAditionalActionLinksProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyAnyDirectoryPanelAditionalActionLinksProvider.java
index 7fa0709..60878a8 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyAnyDirectoryPanelAditionalActionLinksProvider.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyAnyDirectoryPanelAditionalActionLinksProvider.java
@@ -31,6 +31,8 @@ import org.apache.wicket.PageReference;
 public class EmptyAnyDirectoryPanelAditionalActionLinksProvider
         implements AnyDirectoryPanelAditionalActionLinksProvider {
 
+    private static final long serialVersionUID = 121356001392126568L;
+
     @Override
     public List<Action<UserTO>> get(
             final UserTO modelObject,
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyExternalResourceProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyExternalResourceProvider.java
index 38fa725..3437a55 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyExternalResourceProvider.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyExternalResourceProvider.java
@@ -23,6 +23,8 @@ import java.util.List;
 
 public class EmptyExternalResourceProvider implements ExternalResourceProvider {
 
+    private static final long serialVersionUID = 3002474783308961295L;
+
     @Override
     public List<String> get() {
         return Collections.emptyList();
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyStatusProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyStatusProvider.java
index ee0315a..0dd9f44 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyStatusProvider.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyStatusProvider.java
@@ -28,6 +28,8 @@ import org.apache.syncope.common.lib.to.ConnObjectTO;
 
 public class EmptyStatusProvider implements StatusProvider {
 
+    private static final long serialVersionUID = -7948190795547208134L;
+
     @Override
     public List<Triple<ConnObjectTO, ConnObjectWrapper, String>> get(
             final AnyTO any, final Collection<String> resources) {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyVirSchemaDetailsPanelProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyVirSchemaDetailsPanelProvider.java
index 0ad46f3..dfcb293 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyVirSchemaDetailsPanelProvider.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/EmptyVirSchemaDetailsPanelProvider.java
@@ -24,6 +24,8 @@ import org.apache.wicket.markup.html.panel.Panel;
 
 public class EmptyVirSchemaDetailsPanelProvider implements VirSchemaDetailsPanelProvider {
 
+    private static final long serialVersionUID = 1972241879030801082L;
+
     @Override
     public Panel get(final String id, final VirSchemaTO schemaTO) {
         return new EmptyPanel(id);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/ExternalResourceProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/ExternalResourceProvider.java
index 4bdb080..1f58363 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/ExternalResourceProvider.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/ExternalResourceProvider.java
@@ -18,9 +18,10 @@
  */
 package org.apache.syncope.client.console.commons;
 
+import java.io.Serializable;
 import java.util.List;
 
-public interface ExternalResourceProvider {
+public interface ExternalResourceProvider extends Serializable {
 
     List<String> get();
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/PreviewUtils.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/PreviewUtils.java
index 13ce3ba..fc85cb5 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/PreviewUtils.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/PreviewUtils.java
@@ -19,25 +19,18 @@
 package org.apache.syncope.client.console.commons;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
 import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.console.init.ConsoleInitializer;
 import org.apache.syncope.client.console.wicket.markup.html.form.preview.AbstractBinaryPreviewer;
 import org.apache.syncope.client.console.wicket.markup.html.form.preview.DefaultPreviewer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 import org.springframework.util.ClassUtils;
 
-public final class PreviewUtils {
+@Component
+public class PreviewUtils {
 
-    public static PreviewUtils getInstance() {
-        return new PreviewUtils();
-    }
-
-    private final ClassPathScanImplementationLookup classPathScanImplementationLookup;
-
-    private PreviewUtils() {
-        classPathScanImplementationLookup = (ClassPathScanImplementationLookup) SyncopeConsoleApplication.get().
-                getServletContext().getAttribute(ConsoleInitializer.CLASSPATH_LOOKUP);
-    }
+    @Autowired
+    private ClassPathScanImplementationLookup lookup;
 
     public AbstractBinaryPreviewer getDefaultPreviewer(final String mimeType) {
         return new DefaultPreviewer("previewer", mimeType);
@@ -48,13 +41,12 @@ public final class PreviewUtils {
             return null;
         }
 
-        Class<? extends AbstractBinaryPreviewer> previewer =
-                classPathScanImplementationLookup.getPreviewerClass(mimeType);
+        Class<? extends AbstractBinaryPreviewer> previewer = lookup.getPreviewerClass(mimeType);
         try {
             return previewer == null
                     ? null
                     : ClassUtils.getConstructorIfAvailable(previewer, String.class, String.class).
-                    newInstance(new Object[] { "previewer", mimeType });
+                            newInstance(new Object[] { "previewer", mimeType });
         } catch (Exception e) {
             return null;
         }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/StatusProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/StatusProvider.java
index 94a0361..a098cf8 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/StatusProvider.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/StatusProvider.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.commons;
 
+import java.io.Serializable;
 import java.util.Collection;
 import java.util.List;
 import org.apache.commons.lang3.tuple.Triple;
@@ -25,7 +26,7 @@ import org.apache.syncope.client.console.commons.status.ConnObjectWrapper;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 
-public interface StatusProvider {
+public interface StatusProvider extends Serializable {
 
     List<Triple<ConnObjectTO, ConnObjectWrapper, String>> get(AnyTO any, Collection<String> resources);
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/VirSchemaDetailsPanelProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/VirSchemaDetailsPanelProvider.java
index 77eda05..83a68d1 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/VirSchemaDetailsPanelProvider.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/VirSchemaDetailsPanelProvider.java
@@ -18,10 +18,11 @@
  */
 package org.apache.syncope.client.console.commons;
 
+import java.io.Serializable;
 import org.apache.syncope.common.lib.to.VirSchemaTO;
 import org.apache.wicket.markup.html.panel.Panel;
 
-public interface VirSchemaDetailsPanelProvider {
+public interface VirSchemaDetailsPanelProvider extends Serializable {
 
     Panel get(String id, VirSchemaTO schemaTO);
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ConsoleInitializer.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ConsoleInitializer.java
deleted file mode 100644
index c93da79..0000000
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ConsoleInitializer.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.console.init;
-
-import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-import javax.servlet.annotation.WebListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Take care of all initializations needed by Syncope Console to run up and safe.
- */
-@WebListener
-public class ConsoleInitializer implements ServletContextListener {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ConsoleInitializer.class);
-
-    public static final String CLASSPATH_LOOKUP = "CLASSPATH_LOOKUP";
-
-    public static final String MIMETYPES_LOADER = "MIMETYPES_LOADER";
-
-    @Override
-    public void contextInitialized(final ServletContextEvent sce) {
-        ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup();
-        lookup.load();
-        sce.getServletContext().setAttribute(CLASSPATH_LOOKUP, lookup);
-
-        MIMETypesLoader mimeTypes = new MIMETypesLoader();
-        mimeTypes.load();
-        sce.getServletContext().setAttribute(MIMETYPES_LOADER, mimeTypes);
-
-        LOG.debug("Initialization completed");
-    }
-
-    @Override
-    public void contextDestroyed(final ServletContextEvent sce) {
-        // nothing to do
-    }
-}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
index f5dd694..36b9155 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
@@ -23,14 +23,12 @@ import java.lang.reflect.Constructor;
 import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.annotations.ExtPage;
 import org.apache.syncope.client.console.annotations.IdMPage;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.HttpResourceStream;
 import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.console.init.ConsoleInitializer;
 import org.apache.syncope.client.console.panels.NotificationPanel;
 import org.apache.syncope.client.console.rest.ConfRestClient;
 import org.apache.syncope.client.console.wicket.markup.head.MetaHeaderItem;
@@ -66,6 +64,7 @@ import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.resource.ContentDisposition;
+import org.apache.wicket.spring.injection.annot.SpringBean;
 import org.apache.wicket.util.time.Duration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -78,6 +77,9 @@ public class BasePage extends WebPage implements IAjaxIndicatorAware {
 
     protected static final HeaderItem META_IE_EDGE = new MetaHeaderItem("X-UA-Compatible", "IE=edge");
 
+    @SpringBean
+    protected ClassPathScanImplementationLookup lookup;
+
     protected final WebMarkupContainer body;
 
     protected NotificationPanel notificationPanel;
@@ -89,9 +91,6 @@ public class BasePage extends WebPage implements IAjaxIndicatorAware {
     public BasePage(final PageParameters parameters) {
         super(parameters);
 
-        ClassPathScanImplementationLookup lookup = (ClassPathScanImplementationLookup) SyncopeConsoleApplication.get().
-                getServletContext().getAttribute(ConsoleInitializer.CLASSPATH_LOOKUP);
-
         body = new WebMarkupContainer("body");
         Serializable leftMenuCollapse = SyncopeConsoleSession.get().getAttribute(Constants.MENU_COLLAPSE);
         if ((leftMenuCollapse instanceof Boolean) && ((Boolean) leftMenuCollapse)) {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java
index eb27288..1757bf6 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java
@@ -21,9 +21,6 @@ package org.apache.syncope.client.console.pages;
 import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
 import java.util.ArrayList;
 import java.util.List;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
-import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.console.init.ConsoleInitializer;
 import org.apache.syncope.client.console.panels.DashboardAccessTokensPanel;
 import org.apache.syncope.client.console.panels.DashboardControlPanel;
 import org.apache.syncope.client.console.panels.DashboardExtensionsPanel;
@@ -82,11 +79,7 @@ public class Dashboard extends BasePage {
             }
         });
 
-        ClassPathScanImplementationLookup classPathScanImplementationLookup =
-                (ClassPathScanImplementationLookup) SyncopeConsoleApplication.get().
-                        getServletContext().getAttribute(ConsoleInitializer.CLASSPATH_LOOKUP);
-        final List<Class<? extends BaseExtWidget>> extWidgetClasses =
-                classPathScanImplementationLookup.getExtWidgetClasses();
+        List<Class<? extends BaseExtWidget>> extWidgetClasses = lookup.getExtWidgetClasses();
         if (!extWidgetClasses.isEmpty()) {
             tabs.add(new AbstractTab(new ResourceModel("extensions")) {
 
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Login.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
index 488494d..a1e0ebe 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
@@ -23,11 +23,10 @@ import java.security.AccessControlException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.console.init.ConsoleInitializer;
 import org.apache.syncope.client.console.panels.NotificationPanel;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -47,6 +46,7 @@ import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.spring.injection.annot.SpringBean;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -56,6 +56,9 @@ public class Login extends WebPage {
 
     private static final long serialVersionUID = 5889157642852559004L;
 
+    @SpringBean
+    private ClassPathScanImplementationLookup lookup;
+
     private final NotificationPanel notificationPanel;
 
     private final StatelessForm<Void> form;
@@ -111,7 +114,7 @@ public class Login extends WebPage {
         form.add(languageSelect);
 
         DomainDropDown domainSelect = new DomainDropDown("domain");
-        if (SyncopeConsoleApplication.get().getDomains().size() == 1) {
+        if (SyncopeWebApplication.get().getDomains().size() == 1) {
             domainSelect.setOutputMarkupPlaceholderTag(true);
         }
         domainSelect.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
@@ -139,7 +142,7 @@ public class Login extends WebPage {
 
             @Override
             protected void onSubmit(final AjaxRequestTarget target) {
-                if (SyncopeConsoleApplication.get().getAnonymousUser().equals(usernameField.getRawInput())) {
+                if (SyncopeWebApplication.get().getAnonymousUser().equals(usernameField.getRawInput())) {
                     throw new AccessControlException("Illegal username");
                 }
 
@@ -161,11 +164,8 @@ public class Login extends WebPage {
         form.add(submitButton);
         form.setDefaultButton(submitButton);
 
-        ClassPathScanImplementationLookup classPathScanImplementationLookup =
-                (ClassPathScanImplementationLookup) SyncopeConsoleApplication.get().
-                        getServletContext().getAttribute(ConsoleInitializer.CLASSPATH_LOOKUP);
         List<Panel> ssoLoginFormPanels = new ArrayList<>();
-        classPathScanImplementationLookup.getSSOLoginFormPanels().forEach(ssoLoginFormPanel -> {
+        lookup.getSSOLoginFormPanels().forEach(ssoLoginFormPanel -> {
             try {
                 ssoLoginFormPanels.add(ssoLoginFormPanel.getConstructor(String.class).newInstance("ssoLogin"));
             } catch (Exception e) {
@@ -204,7 +204,7 @@ public class Login extends WebPage {
         }
 
         LocaleDropDown(final String id) {
-            super(id, SyncopeConsoleApplication.SUPPORTED_LOCALES);
+            super(id, SyncopeWebApplication.SUPPORTED_LOCALES);
 
             setChoiceRenderer(new LocaleRenderer());
             setModel(new IModel<Locale>() {
@@ -240,7 +240,7 @@ public class Login extends WebPage {
         private static final long serialVersionUID = -7401167913360133325L;
 
         DomainDropDown(final String id) {
-            super(id, SyncopeConsoleApplication.get().getDomains());
+            super(id, SyncopeWebApplication.get().getDomains());
 
             setModel(new IModel<String>() {
 
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
index 1287f50..ad064ed 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
@@ -22,7 +22,7 @@ import java.io.Serializable;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.notifications.NotificationTasks;
@@ -131,7 +131,7 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO
         }, ActionType.CLONE, AnyEntitlement.CREATE.getFor(type)).setRealm(realm);
 
         if (wizardInModal) {
-            SyncopeConsoleApplication.get().getAnyDirectoryPanelAditionalActionLinksProvider().get(
+            SyncopeWebApplication.get().getAnyDirectoryPanelAditionalActionLinksProvider().get(
                     type,
                     model.getObject(),
                     realm,
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DashboardOverviewPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DashboardOverviewPanel.java
index db017d8..7776fcd 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DashboardOverviewPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DashboardOverviewPanel.java
@@ -30,6 +30,7 @@ import org.apache.syncope.common.lib.info.NumbersInfo;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.util.time.Duration;
 
 public class DashboardOverviewPanel extends Panel {
@@ -63,11 +64,12 @@ public class DashboardOverviewPanel extends Panel {
         container.setOutputMarkupId(true);
         add(container);
 
-        totalUsers = new NumberWidget(
-                "totalUsers", "bg-yellow", numbers.getTotalUsers(), getString("users"), "ion ion-person");
+        totalUsers = new NumberWidget("totalUsers", "bg-yellow", numbers.getTotalUsers(),
+                new ResourceModel("users").getObject(), "ion ion-person");
         container.add(totalUsers);
         totalGroups = new NumberWidget(
-                "totalGroups", "bg-red", numbers.getTotalGroups(), getString("groups"), "ion ion-person-stalker");
+                "totalGroups", "bg-red", numbers.getTotalGroups(),
+                new ResourceModel("groups").getObject(), "ion ion-person-stalker");
         container.add(totalGroups);
 
         Triple<Integer, String, String> built = buildTotalAny1OrRoles(numbers);
@@ -154,7 +156,7 @@ public class DashboardOverviewPanel extends Panel {
         String icon;
         if (numbers.getAnyType1() == null) {
             number = numbers.getTotalRoles();
-            label = getString("roles");
+            label = new ResourceModel("roles").getObject();
             icon = "fa fa-users";
         } else {
             number = numbers.getTotalAny1();
@@ -170,7 +172,7 @@ public class DashboardOverviewPanel extends Panel {
         String icon;
         if (numbers.getAnyType2() == null) {
             number = numbers.getTotalResources();
-            label = getString("resources");
+            label = new ResourceModel("resources").getObject();
             icon = "fa fa-database";
         } else {
             number = numbers.getTotalAny2();
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
index 7f2016e..2c7e192 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
@@ -24,7 +24,7 @@ import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.layout.FormLayoutInfoUtils;
@@ -309,7 +309,7 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli
                 String.format("%s,%s", StandardEntitlement.TASK_CREATE, StandardEntitlement.TASK_EXECUTE)).
                 setRealm(realm);
 
-        SyncopeConsoleApplication.get().getAnyDirectoryPanelAditionalActionLinksProvider().get(
+        SyncopeWebApplication.get().getAnyDirectoryPanelAditionalActionLinksProvider().get(
                 model.getObject(),
                 realm,
                 altDefaultModal,
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationModalPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationModalPanel.java
index 46f4be5..3b7ddd2 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationModalPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationModalPanel.java
@@ -27,11 +27,9 @@ import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.console.init.ConsoleInitializer;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.rest.ImplementationRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
@@ -50,6 +48,7 @@ import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.TextArea;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
 import org.apache.wicket.util.io.IOUtils;
 
 public class ImplementationModalPanel extends AbstractModalPanel<ImplementationTO> {
@@ -65,6 +64,9 @@ public class ImplementationModalPanel extends AbstractModalPanel<ImplementationT
 
     private static final ObjectMapper MAPPER = new ObjectMapper();
 
+    @SpringBean
+    private ClassPathScanImplementationLookup lookup;
+
     private final ImplementationRestClient restClient = new ImplementationRestClient();
 
     private final ImplementationTO implementation;
@@ -103,33 +105,29 @@ public class ImplementationModalPanel extends AbstractModalPanel<ImplementationT
                     ? new ArrayList<>(javaClasses.get().getClasses())
                     : new ArrayList<>();
         } else if (viewMode == ViewMode.JSON_BODY) {
-            ClassPathScanImplementationLookup implementationLookup =
-                    (ClassPathScanImplementationLookup) SyncopeConsoleApplication.get().
-                            getServletContext().getAttribute(ConsoleInitializer.CLASSPATH_LOOKUP);
-
             switch (implementation.getType()) {
                 case REPORTLET:
-                    classes = implementationLookup.getReportletConfs().keySet().stream().
+                    classes = lookup.getReportletConfs().keySet().stream().
                             collect(Collectors.toList());
                     break;
 
                 case ACCOUNT_RULE:
-                    classes = implementationLookup.getAccountRuleConfs().keySet().stream().
+                    classes = lookup.getAccountRuleConfs().keySet().stream().
                             collect(Collectors.toList());
                     break;
 
                 case PASSWORD_RULE:
-                    classes = implementationLookup.getPasswordRuleConfs().keySet().stream().
+                    classes = lookup.getPasswordRuleConfs().keySet().stream().
                             collect(Collectors.toList());
                     break;
 
                 case PULL_CORRELATION_RULE:
-                    classes = implementationLookup.getPullCorrelationRuleConfs().keySet().stream().
+                    classes = lookup.getPullCorrelationRuleConfs().keySet().stream().
                             collect(Collectors.toList());
                     break;
 
                 case PUSH_CORRELATION_RULE:
-                    classes = implementationLookup.getPushCorrelationRuleConfs().keySet().stream().
+                    classes = lookup.getPushCorrelationRuleConfs().keySet().stream().
                             collect(Collectors.toList());
                     break;
 
@@ -263,30 +261,26 @@ public class ImplementationModalPanel extends AbstractModalPanel<ImplementationT
 
             @Override
             protected void onEvent(final AjaxRequestTarget target) {
-                ClassPathScanImplementationLookup implementationLookup =
-                        (ClassPathScanImplementationLookup) SyncopeConsoleApplication.get().
-                                getServletContext().getAttribute(ConsoleInitializer.CLASSPATH_LOOKUP);
-
                 Class<?> clazz = null;
                 switch (implementation.getType()) {
                     case REPORTLET:
-                        clazz = implementationLookup.getReportletConfs().get(jsonClass.getModelObject());
+                        clazz = lookup.getReportletConfs().get(jsonClass.getModelObject());
                         break;
 
                     case ACCOUNT_RULE:
-                        clazz = implementationLookup.getAccountRuleConfs().get(jsonClass.getModelObject());
+                        clazz = lookup.getAccountRuleConfs().get(jsonClass.getModelObject());
                         break;
 
                     case PASSWORD_RULE:
-                        clazz = implementationLookup.getPasswordRuleConfs().get(jsonClass.getModelObject());
+                        clazz = lookup.getPasswordRuleConfs().get(jsonClass.getModelObject());
                         break;
 
                     case PULL_CORRELATION_RULE:
-                        clazz = implementationLookup.getPullCorrelationRuleConfs().get(jsonClass.getModelObject());
+                        clazz = lookup.getPullCorrelationRuleConfs().get(jsonClass.getModelObject());
                         break;
 
                     case PUSH_CORRELATION_RULE:
-                        clazz = implementationLookup.getPushCorrelationRuleConfs().get(jsonClass.getModelObject());
+                        clazz = lookup.getPushCorrelationRuleConfs().get(jsonClass.getModelObject());
                         break;
 
                     default:
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ParametersCreateWizardSchemaStep.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ParametersCreateWizardSchemaStep.java
index 4eed5ad..e81fd1e 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ParametersCreateWizardSchemaStep.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ParametersCreateWizardSchemaStep.java
@@ -22,10 +22,8 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.PropertyList;
-import org.apache.syncope.client.console.init.ConsoleInitializer;
 import org.apache.syncope.client.console.init.MIMETypesLoader;
 import org.apache.syncope.client.console.rest.ImplementationRestClient;
 import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
@@ -46,13 +44,14 @@ import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
 
 public class ParametersCreateWizardSchemaStep extends WizardStep {
 
     private static final long serialVersionUID = -7843275202297616553L;
 
-    private static final MIMETypesLoader MIME_TYPES_LOADER = (MIMETypesLoader) SyncopeConsoleApplication.get().
-            getServletContext().getAttribute(ConsoleInitializer.MIMETYPES_LOADER);
+    @SpringBean
+    private MIMETypesLoader mimeTypesLoader;
 
     private final ImplementationRestClient implRestClient = new ImplementationRestClient();
 
@@ -357,7 +356,8 @@ public class ParametersCreateWizardSchemaStep extends WizardStep {
             cipherAlgorithm.setModelObject(null);
 
             binaryParams.setVisible(true);
-            mimeType.setChoices(MIME_TYPES_LOADER.getMimeTypes());
+            mimeType.setChoices(mimeTypesLoader.getMimeTypes());
+
             schema.setValidator("BinaryValidator");
         } else {
             conversionParams.setVisible(false);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/PlainSchemaDetails.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/PlainSchemaDetails.java
index 310864d..c91e436 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/PlainSchemaDetails.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/PlainSchemaDetails.java
@@ -26,10 +26,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.PropertyList;
-import org.apache.syncope.client.console.init.ConsoleInitializer;
 import org.apache.syncope.client.console.init.MIMETypesLoader;
 import org.apache.syncope.client.console.rest.ImplementationRestClient;
 import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
@@ -50,14 +48,15 @@ import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
 import org.apache.wicket.util.string.Strings;
 
 public class PlainSchemaDetails extends AbstractSchemaDetailsPanel {
 
     private static final long serialVersionUID = 5378100729213456451L;
 
-    private static final MIMETypesLoader MIME_TYPES_LOADER = (MIMETypesLoader) SyncopeConsoleApplication.get().
-            getServletContext().getAttribute(ConsoleInitializer.MIMETYPES_LOADER);
+    @SpringBean
+    private MIMETypesLoader mimeTypesLoader;
 
     private final ImplementationRestClient implRestClient = new ImplementationRestClient();
 
@@ -393,7 +392,7 @@ public class PlainSchemaDetails extends AbstractSchemaDetailsPanel {
             cipherAlgorithm.setModelObject(null);
 
             binaryParams.setVisible(true);
-            mimeType.setChoices(MIME_TYPES_LOADER.getMimeTypes());
+            mimeType.setChoices(mimeTypesLoader.getMimeTypes());
 
             schema.setValidator("BinaryValidator");
         } else {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
index 303ec8e..73d18ca 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
@@ -28,7 +28,7 @@ import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.commons.lang3.tuple.Triple;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.commons.ConnIdSpecialName;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.ITabComponent;
@@ -163,7 +163,7 @@ public abstract class Realm extends WizardMgtPanel<RealmTO> {
 
             @Override
             public boolean isVisible() {
-                return SyncopeConsoleApplication.get().getSecuritySettings().getAuthorizationStrategy().
+                return SyncopeWebApplication.get().getSecuritySettings().getAuthorizationStrategy().
                         isActionAuthorized(this, RENDER);
             }
         });
@@ -184,7 +184,7 @@ public abstract class Realm extends WizardMgtPanel<RealmTO> {
 
                 @Override
                 public boolean isVisible() {
-                    return SyncopeConsoleApplication.get().getSecuritySettings().getAuthorizationStrategy().
+                    return SyncopeWebApplication.get().getSecuritySettings().getAuthorizationStrategy().
                             isActionAuthorized(this, RENDER);
                 }
             });
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
index f6f31b3..5371af3 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
@@ -22,7 +22,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.rest.ImplementationRestClient;
 import org.apache.syncope.client.console.rest.PolicyRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
@@ -97,7 +97,7 @@ public class RealmDetails extends Panel {
 
         @Override
         protected List<String> load() {
-            return SyncopeConsoleApplication.get().getResourceProvider().get();
+            return SyncopeWebApplication.get().getResourceProvider().get();
         }
     };
 
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypeWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypeWizardBuilder.java
index e9629d8..ad75eb4 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypeWizardBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypeWizardBuilder.java
@@ -27,7 +27,7 @@ import java.util.stream.Collectors;
 import org.apache.commons.lang3.LocaleUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.MutablePair;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.rest.SchemaRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
@@ -115,7 +115,7 @@ public class SchemaTypeWizardBuilder extends AjaxWizardBuilder<SchemaTO> {
                     break;
 
                 case VIRTUAL:
-                    detailsPanel = SyncopeConsoleApplication.get().getVirSchemaDetailsPanelProvider().
+                    detailsPanel = SyncopeWebApplication.get().getVirSchemaDetailsPanelProvider().
                             get("details", (VirSchemaTO) modelObject);
                     break;
 
@@ -166,7 +166,7 @@ public class SchemaTypeWizardBuilder extends AjaxWizardBuilder<SchemaTO> {
                         }
                     });
                     locale.setRequired(true).hideLabel();
-                    locale.setChoices(SyncopeConsoleApplication.SUPPORTED_LOCALES.stream().
+                    locale.setChoices(SyncopeWebApplication.SUPPORTED_LOCALES.stream().
                             map(Objects::toString).collect(Collectors.toList()));
                     locale.addValidator(validatable -> {
                         try {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
index f499245..1305213 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
@@ -24,7 +24,7 @@ import java.util.Collection;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.notifications.NotificationTasks;
@@ -236,7 +236,7 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
                         setRealms(realm, model.getObject().getDynRealms());
             }
 
-            SyncopeConsoleApplication.get().getAnyDirectoryPanelAditionalActionLinksProvider().get(
+            SyncopeWebApplication.get().getAnyDirectoryPanelAditionalActionLinksProvider().get(
                     model.getObject(),
                     realm,
                     altDefaultModal,
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
index 30d254f..28b4ce1 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
@@ -24,7 +24,7 @@ import java.util.Map;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.rest.GroupRestClient;
@@ -194,7 +194,7 @@ public abstract class AbstractSearchPanel extends Panel {
 
             @Override
             protected List<String> load() {
-                return SyncopeConsoleApplication.get().getResourceProvider().get();
+                return SyncopeWebApplication.get().getResourceProvider().get();
             }
         };
     }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyModalPanelBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyModalPanelBuilder.java
index d199dc0..2fe8133 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyModalPanelBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyModalPanelBuilder.java
@@ -23,7 +23,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.pages.BasePage;
@@ -89,7 +89,7 @@ public class PolicyModalPanelBuilder<T extends PolicyTO> extends AbstractModalPa
 
             @Override
             protected List<String> load() {
-                return SyncopeConsoleApplication.get().getResourceProvider().get();
+                return SyncopeWebApplication.get().getResourceProvider().get();
             }
         };
 
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDownload.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDownload.java
index 6ede95f..cac77e3 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDownload.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDownload.java
@@ -19,22 +19,21 @@
 package org.apache.syncope.client.console.wicket.markup.html.form;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
 import org.apache.syncope.client.console.commons.HttpResourceStream;
-import org.apache.syncope.client.console.init.ConsoleInitializer;
 import org.apache.syncope.client.console.init.MIMETypesLoader;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.behavior.AbstractAjaxBehavior;
 import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
 import org.apache.wicket.request.resource.ContentDisposition;
+import org.apache.wicket.spring.injection.annot.SpringBean;
 import org.apache.wicket.util.time.Duration;
 
 public abstract class AjaxDownload extends AbstractAjaxBehavior {
 
     private static final long serialVersionUID = 7203445884857810583L;
 
-    private static final MIMETypesLoader MIME_TYPES_LOADER = (MIMETypesLoader) SyncopeConsoleApplication.get().
-            getServletContext().getAttribute(ConsoleInitializer.MIMETYPES_LOADER);
+    @SpringBean
+    private MIMETypesLoader mimeTypesLoader;
 
     private final String name;
 
@@ -73,7 +72,7 @@ public abstract class AjaxDownload extends AbstractAjaxBehavior {
         String key = StringUtils.isNotBlank(fileKey) ? fileKey + "_" : "";
         String ext = "";
         if (StringUtils.isNotBlank(mimeType)) {
-            String extByMimeType = MIME_TYPES_LOADER.getFileExt(mimeType);
+            String extByMimeType = mimeTypesLoader.getFileExt(mimeType);
             ext = StringUtils.isBlank(extByMimeType) ? ".bin" : ("." + extByMimeType);
         }
         String fileName = key + (stream.getFilename() == null ? name : stream.getFilename()) + ext;
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
index 38676f2..e380ceb 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
@@ -31,7 +31,7 @@ import java.util.Base64;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.HttpResourceStream;
@@ -55,13 +55,15 @@ import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.model.util.ListModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
 import org.apache.wicket.util.lang.Bytes;
 
 public class BinaryFieldPanel extends FieldPanel<String> {
 
     private static final long serialVersionUID = 6264462604183088931L;
 
-    private static final PreviewUtils PREVIEW_UTILS = PreviewUtils.getInstance();
+    @SpringBean
+    private PreviewUtils previewUtils;
 
     private final String mimeType;
 
@@ -93,16 +95,17 @@ public class BinaryFieldPanel extends FieldPanel<String> {
             final IModel<String> model,
             final String mimeType,
             final String fileKey) {
+
         super(id, name, model);
         this.model = model;
         this.fileKey = fileKey;
         this.mimeType = mimeType;
 
-        previewer = PREVIEW_UTILS.getPreviewer(mimeType);
+        previewer = previewUtils.getPreviewer(mimeType);
 
-        maxUploadSize = SyncopeConsoleApplication.get().getMaxUploadFileSizeMB() == null
+        maxUploadSize = SyncopeWebApplication.get().getMaxUploadFileSizeMB() == null
                 ? null
-                : Bytes.megabytes(SyncopeConsoleApplication.get().getMaxUploadFileSizeMB());
+                : Bytes.megabytes(SyncopeWebApplication.get().getMaxUploadFileSizeMB());
         uploadForm = new StatelessForm<>("uploadForm");
         uploadForm.setMultiPart(true);
         add(uploadForm);
@@ -274,7 +277,7 @@ public class BinaryFieldPanel extends FieldPanel<String> {
         if (StringUtils.isNotBlank(modelObj)) {
             final Component panelPreview;
             if (previewer == null) {
-                panelPreview = PREVIEW_UTILS.getDefaultPreviewer(mimeType);
+                panelPreview = previewUtils.getDefaultPreviewer(mimeType);
             } else {
                 panelPreview = previewer.preview(modelObj);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ImageModalPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ImageModalPanel.java
index cf9c108..48d42c6 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ImageModalPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ImageModalPanel.java
@@ -54,5 +54,4 @@ public class ImageModalPanel<T extends Serializable> extends AbstractModalPanel<
         image.setOutputMarkupId(true);
         add(image);
     }
-
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationWidget.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationWidget.java
index 526e5ab..ffa2e54 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationWidget.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationWidget.java
@@ -33,7 +33,7 @@ import java.util.Set;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.DirectoryDataProvider;
@@ -122,12 +122,12 @@ public class ReconciliationWidget extends BaseWidget {
                 if (isCheckReconciliationJob()) {
                     try {
                         restClient.listJobs().stream().
-                                filter(jobTO -> SyncopeConsoleApplication.get().
+                                filter(jobTO -> SyncopeWebApplication.get().
                                 getReconciliationReportKey().equals(jobTO.getRefKey())).
                                 findFirst().ifPresent(reportJobTO -> {
                                     if (!reportJobTO.isRunning()) {
                                         LOG.debug("Report {} is not running",
-                                                SyncopeConsoleApplication.get().getReconciliationReportKey());
+                                                SyncopeWebApplication.get().getReconciliationReportKey());
 
                                         overlay.setVisible(false);
 
@@ -150,7 +150,7 @@ public class ReconciliationWidget extends BaseWidget {
         overlay.setVisible(false);
         container.add(overlay);
 
-        this.reconciliationReportKey = SyncopeConsoleApplication.get().getReconciliationReportKey();
+        this.reconciliationReportKey = SyncopeWebApplication.get().getReconciliationReportKey();
 
         ReportTO reconciliationReport = null;
         if (SyncopeConsoleSession.get().owns(StandardEntitlement.REPORT_READ)) {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
index 2552b4c..c797633 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
@@ -29,7 +29,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.wicket.Component;
@@ -382,7 +382,7 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard
                     SyncopeConsoleSession.get().execute(new ApplyFuture(target));
 
             Pair<Serializable, Serializable> res =
-                    executor.get(SyncopeConsoleApplication.get().getMaxWaitTimeInSeconds(), TimeUnit.SECONDS);
+                    executor.get(SyncopeWebApplication.get().getMaxWaitTimeInSeconds(), TimeUnit.SECONDS);
 
             if (res.getLeft() != null) {
                 send(pageRef.getPage(), Broadcast.BUBBLE, res.getLeft());
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
index 85c055c..e91e667 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.client.console.wizards.any;
 
 import java.util.List;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.layout.AbstractAnyFormLayout;
 import org.apache.syncope.client.console.layout.AnyForm;
 import org.apache.syncope.client.console.layout.AnyObjectFormLayoutInfo;
@@ -155,7 +155,7 @@ public abstract class AnyWizardBuilder<A extends AnyTO> extends AjaxWizardBuilde
             wizardModel.add(new Relationships(modelObject, pageRef));
         }
 
-        SyncopeConsoleApplication.get().getAnyWizardBuilderAdditionalSteps().
+        SyncopeWebApplication.get().getAnyWizardBuilderAdditionalSteps().
                 buildModelSteps(modelObject, wizardModel, formLayoutInfo);
 
         return wizardModel;
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
index 8333782..6594b13 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
@@ -27,7 +27,7 @@ import java.util.stream.Collectors;
 import org.apache.commons.collections4.ListUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.rest.DynRealmRestClient;
 import org.apache.syncope.client.console.rest.GroupRestClient;
@@ -209,7 +209,7 @@ public class Groups extends WizardStep implements ICondition {
         return (anyTO instanceof GroupTO
                 ? !allDynRealms.isEmpty()
                 : !allDynRealms.isEmpty() || !groupsModel.getObject().isEmpty())
-                && SyncopeConsoleApplication.get().getSecuritySettings().getAuthorizationStrategy().
+                && SyncopeWebApplication.get().getSecuritySettings().getAuthorizationStrategy().
                         isActionAuthorized(this, RENDER);
     }
 
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java
index 6e9a892..859c71d 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java
@@ -24,7 +24,7 @@ import java.util.ArrayList;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.search.AnySelectionDirectoryPanel;
 import org.apache.syncope.client.console.panels.search.GroupSearchPanel;
@@ -344,7 +344,7 @@ public class Ownership extends WizardStep implements ICondition {
 
     @Override
     public boolean evaluate() {
-        return SyncopeConsoleApplication.get().getSecuritySettings().getAuthorizationStrategy().
+        return SyncopeWebApplication.get().getSecuritySettings().getAuthorizationStrategy().
                 isActionAuthorized(this, RENDER);
     }
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java
index b48b63f..5c13dbe 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java
@@ -22,7 +22,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.wicket.ajax.markup.html.LabelInfo;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
 import org.apache.syncope.common.lib.to.AnyTO;
@@ -86,9 +86,9 @@ public class Resources extends WizardStep implements ICondition {
 
     @Override
     public boolean evaluate() {
-        if (SyncopeConsoleApplication.get().getSecuritySettings().
+        if (SyncopeWebApplication.get().getSecuritySettings().
                 getAuthorizationStrategy().isActionAuthorized(this, RENDER)) {
-            available.setObject(SyncopeConsoleApplication.get().getResourceProvider().get());
+            available.setObject(SyncopeWebApplication.get().getResourceProvider().get());
             return !available.getObject().isEmpty();
         } else {
             return false;
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java
index 974d7e9..913e867 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java
@@ -24,7 +24,7 @@ import java.util.stream.Collectors;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.ListUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.rest.RoleRestClient;
 import org.apache.syncope.client.console.wicket.ajax.markup.html.LabelInfo;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
@@ -73,7 +73,7 @@ public class Roles extends WizardStep implements ICondition {
 
         this.setOutputMarkupId(true);
 
-        allRoles = SyncopeConsoleApplication.get().getSecuritySettings().getAuthorizationStrategy().
+        allRoles = SyncopeWebApplication.get().getSecuritySettings().getAuthorizationStrategy().
                 isActionAuthorized(this, RENDER)
                 ? new RoleRestClient().list().stream().map(EntityTO::getKey).collect(Collectors.toList())
                 : Collections.<String>emptyList();
@@ -91,7 +91,7 @@ public class Roles extends WizardStep implements ICondition {
     @Override
     public final boolean evaluate() {
         return CollectionUtils.isNotEmpty(allRoles)
-                && SyncopeConsoleApplication.get().getSecuritySettings().getAuthorizationStrategy().
+                && SyncopeWebApplication.get().getSecuritySettings().getAuthorizationStrategy().
                         isActionAuthorized(this, RENDER);
     }
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
index 061b75d..3857969 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
@@ -26,7 +26,7 @@ import java.util.Map;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.commons.lang3.tuple.Triple;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.status.ConnObjectWrapper;
 import org.apache.syncope.client.console.commons.status.Status;
@@ -69,7 +69,7 @@ public class StatusPanel extends Panel {
 
         super(id);
         init(any, model,
-                SyncopeConsoleApplication.get().getStatusProvider().get(any, any.getResources()), pageRef, false);
+                SyncopeWebApplication.get().getStatusProvider().get(any, any.getResources()), pageRef, false);
     }
 
     public <T extends AnyTO> StatusPanel(
diff --git a/client/idrepo/console/src/main/resources/META-INF/web-fragment.xml b/client/idrepo/console/src/main/resources/META-INF/web-fragment.xml
deleted file mode 100644
index 092331a..0000000
--- a/client/idrepo/console/src/main/resources/META-INF/web-fragment.xml
+++ /dev/null
@@ -1,46 +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.
--->
-<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee"
-              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
-                                  http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
-              id="${pom.artifactId}" version="3.1">
-    
-  <filter>
-    <filter-name>SyncopeConsole</filter-name>
-    <filter-class>org.apache.wicket.protocol.ws.javax.JavaxWebSocketFilter</filter-class>
-    <init-param>
-      <param-name>filterMappingUrlPattern</param-name>
-      <param-value>/*</param-value>
-    </init-param>
-    <init-param>
-      <param-name>applicationClassName</param-name>
-      <param-value>org.apache.syncope.client.console.SyncopeConsoleApplication</param-value>
-    </init-param>
-  </filter>
-    
-  <filter-mapping>
-    <filter-name>SyncopeConsole</filter-name>
-    <url-pattern>/*</url-pattern>
-    <dispatcher>REQUEST</dispatcher>
-    <dispatcher>INCLUDE</dispatcher>
-  </filter-mapping>
-
-</web-fragment>
diff --git a/core/persistence-jpa/src/test/resources/domains/Two.properties b/client/idrepo/console/src/main/resources/application.properties
similarity index 72%
copy from core/persistence-jpa/src/test/resources/domains/Two.properties
copy to client/idrepo/console/src/main/resources/application.properties
index ea19bd7..ce58400 100644
--- a/core/persistence-jpa/src/test/resources/domains/Two.properties
+++ b/client/idrepo/console/src/main/resources/application.properties
@@ -14,15 +14,12 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-Two.driverClassName=org.h2.Driver
-Two.url=jdbc:h2:file:${conf.directory}/syncopetwo.db
-Two.schema=
-Two.username=sa
-Two.password=
-Two.databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary
-Two.orm=META-INF/spring-orm.xml
+spring.application.name=Apache Syncope ${syncope.version} Console
+spring.groovy.template.check-template-location=false
+spring.main.banner-mode=log
 
-Two.pool.maxActive=10
-Two.pool.minIdle=2
+spring.http.encoding.charset=UTF-8
+spring.http.encoding.enabled=true
+spring.http.encoding.force=true
 
-Two.audit.sql=audit.sql
+server.servlet.contextPath=/syncope-console
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication.properties
similarity index 100%
rename from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication.properties
rename to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication.properties
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_it.properties
similarity index 100%
rename from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_it.properties
rename to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_it.properties
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_ja.properties
similarity index 100%
rename from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_ja.properties
rename to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_ja.properties
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_pt_BR.properties
similarity index 100%
rename from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_pt_BR.properties
rename to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_pt_BR.properties
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_ru.properties
similarity index 100%
rename from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_ru.properties
rename to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_ru.properties
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
index f2ceabc..a9145f0 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
@@ -27,7 +27,6 @@ under the License.
               <i class="fa fa-wrench"></i>
             </button>
             <ul class="dropdown-menu" role="menu">
-              <li><a href="#" wicket:id="topology"><wicket:message key="createResourceOrPullTask"/></a></li>
               <li><a href="#" wicket:id="policies"><wicket:message key="createPolicy"/></a></li>
               <li><a href="#" wicket:id="notifications"><wicket:message key="createNotification"/></a></li>
               <li><a href="#" wicket:id="types"><wicket:message key="createVirSchemaOrAnyType"/></a></li>
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/PropertyUtils.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/PropertyUtils.java
index 7e2f323..95d0958 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/PropertyUtils.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/PropertyUtils.java
@@ -22,7 +22,6 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 import java.util.Properties;
-import org.apache.commons.lang3.tuple.Pair;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -33,18 +32,17 @@ public final class PropertyUtils {
 
     private static final Logger LOG = LoggerFactory.getLogger(PropertyUtils.class);
 
-    public static Pair<Properties, File> read(
+    public static Properties read(
             final Class<?> clazz, final String propertiesFileName, final String confDirProp) {
 
         Properties props = new Properties();
-        File confDir = null;
 
         try (InputStream is = clazz.getResourceAsStream("/" + propertiesFileName)) {
             props.load(is);
 
             String confDirName = props.getProperty(confDirProp);
             if (confDirName != null) {
-                confDir = new File(confDirName);
+                File confDir = new File(confDirName);
                 if (confDir.exists() && confDir.canRead() && confDir.isDirectory()) {
                     File confDirProps = new File(confDir, propertiesFileName);
                     if (confDirProps.exists() && confDirProps.canRead() && confDirProps.isFile()) {
@@ -60,7 +58,7 @@ public final class PropertyUtils {
             throw new RuntimeException("Could not read " + propertiesFileName, e);
         }
 
-        return Pair.of(props, confDir);
+        return props;
     }
 
     /**
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/DomainCR.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/DomainCR.java
new file mode 100644
index 0000000..540eccd
--- /dev/null
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/DomainCR.java
@@ -0,0 +1,197 @@
+/*
+ * 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.common.lib.request;
+
+import java.io.Serializable;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+
+@XmlRootElement(name = "domainCR")
+@XmlType
+public class DomainCR implements Serializable {
+
+    private static final long serialVersionUID = 3842608635517859919L;
+
+    public static class Builder {
+
+        private final DomainCR conf;
+
+        public Builder(final String domainName) {
+            this.conf = new DomainCR();
+            this.conf.domainName = domainName;
+        }
+
+        public Builder jdbcDriver(final String jdbcDriver) {
+            this.conf.jdbcDriver = jdbcDriver;
+            return this;
+        }
+
+        public Builder jdbcURL(final String jdbcURL) {
+            this.conf.jdbcURL = jdbcURL;
+            return this;
+        }
+
+        public Builder dbSchema(final String dbSchema) {
+            if (StringUtils.isNotBlank(dbSchema)) {
+                this.conf.dbSchema = dbSchema;
+            }
+            return this;
+        }
+
+        public Builder dbUsername(final String dbUsername) {
+            this.conf.dbUsername = dbUsername;
+            return this;
+        }
+
+        public Builder dbPassword(final String dbPassword) {
+            this.conf.dbPassword = dbPassword;
+            return this;
+        }
+
+        public Builder transactionIsolation(final String transactionIsolation) {
+            this.conf.transactionIsolation = transactionIsolation;
+            return this;
+        }
+
+        public Builder maxPoolSize(final int maxPoolSize) {
+            this.conf.maxPoolSize = maxPoolSize;
+            return this;
+        }
+
+        public Builder minIdle(final int minIdle) {
+            this.conf.minIdle = minIdle;
+            return this;
+        }
+
+        public Builder auditSql(final String auditSql) {
+            this.conf.auditSql = auditSql;
+            return this;
+        }
+
+        public Builder orm(final String orm) {
+            this.conf.orm = orm;
+            return this;
+        }
+
+        public Builder databasePlatform(final String databasePlatform) {
+            this.conf.databasePlatform = databasePlatform;
+            return this;
+        }
+
+        public Builder adminPassword(final String adminPassword) {
+            this.conf.adminPassword = adminPassword;
+            return this;
+        }
+
+        public Builder adminCipherAlgorithm(final CipherAlgorithm adminCipherAlgorithm) {
+            this.conf.adminCipherAlgorithm = adminCipherAlgorithm;
+            return this;
+        }
+
+        public DomainCR build() {
+            return this.conf;
+        }
+    }
+
+    private String domainName;
+
+    private String jdbcDriver;
+
+    private String jdbcURL;
+
+    private String dbSchema;
+
+    private String dbUsername;
+
+    private String dbPassword;
+
+    private String transactionIsolation = "TRANSACTION_READ_COMMITTED";
+
+    private int maxPoolSize = 10;
+
+    private int minIdle = 2;
+
+    private String auditSql = "audit.sql";
+
+    private String orm = "META-INF/spring-orm.xml";
+
+    private String databasePlatform;
+
+    private String adminPassword;
+
+    private CipherAlgorithm adminCipherAlgorithm = CipherAlgorithm.SHA512;
+
+    public String getDomainName() {
+        return domainName;
+    }
+
+    public String getJdbcDriver() {
+        return jdbcDriver;
+    }
+
+    public String getJdbcURL() {
+        return jdbcURL;
+    }
+
+    public String getDbSchema() {
+        return dbSchema;
+    }
+
+    public String getDbUsername() {
+        return dbUsername;
+    }
+
+    public String getDbPassword() {
+        return dbPassword;
+    }
+
+    public String getTransactionIsolation() {
+        return transactionIsolation;
+    }
+
+    public int getMaxPoolSize() {
+        return maxPoolSize;
+    }
+
+    public int getMinIdle() {
+        return minIdle;
+    }
+
+    public String getAuditSql() {
+        return auditSql;
+    }
+
+    public String getOrm() {
+        return orm;
+    }
+
+    public String getDatabasePlatform() {
+        return databasePlatform;
+    }
+
+    public String getAdminPassword() {
+        return adminPassword;
+    }
+
+    public CipherAlgorithm getAdminCipherAlgorithm() {
+        return adminCipherAlgorithm;
+    }
+}
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
index d606af2..933e877 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
@@ -34,6 +34,7 @@ import org.apache.syncope.core.persistence.api.dao.DuplicateException;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.provisioning.api.data.AnyTypeDataBinder;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.InvalidDataAccessApiUsageException;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
@@ -118,7 +119,7 @@ public class AnyTypeLogic extends AbstractTransactionalLogic<AnyTypeTO> {
 
         try {
             return binder.delete(anyType);
-        } catch (IllegalArgumentException e) {
+        } catch (IllegalArgumentException | InvalidDataAccessApiUsageException e) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRequest);
             sce.getElements().add(e.getMessage());
             throw sce;
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
index c0f144a..a8f4e68 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
@@ -66,6 +66,7 @@ import org.springframework.core.io.support.ResourcePatternResolver;
 import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
 import org.springframework.core.type.classreading.MetadataReader;
 import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.dao.InvalidDataAccessApiUsageException;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
@@ -247,7 +248,7 @@ public class LoggerLogic extends AbstractTransactionalLogic<EntityTO> {
     public void enableAudit(final AuditLoggerName auditLoggerName) {
         try {
             setLevel(auditLoggerName.toLoggerName(), Level.DEBUG, LoggerType.AUDIT);
-        } catch (IllegalArgumentException e) {
+        } catch (IllegalArgumentException | InvalidDataAccessApiUsageException e) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidLogger);
             sce.getElements().add(e.getMessage());
             throw sce;
@@ -299,7 +300,7 @@ public class LoggerLogic extends AbstractTransactionalLogic<EntityTO> {
             delete(auditLoggerName.toLoggerName(), LoggerType.AUDIT);
         } catch (NotFoundException e) {
             LOG.debug("Ignoring disable of non existing logger {}", auditLoggerName.toLoggerName());
-        } catch (IllegalArgumentException e) {
+        } catch (IllegalArgumentException | InvalidDataAccessApiUsageException e) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidLogger);
             sce.getElements().add(e.getMessage());
             throw sce;
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicContext.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicContext.java
new file mode 100644
index 0000000..475e2ef
--- /dev/null
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicContext.java
@@ -0,0 +1,69 @@
+/*
+ * 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.core.logic;
+
+import org.apache.syncope.core.persistence.api.ImplementationLookup;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+
+@PropertySource("classpath:logic.properties")
+@PropertySource(value = "file:${conf.directory}/logic.properties", ignoreResourceNotFound = true)
+@ComponentScan("org.apache.syncope.core.logic")
+@EnableAspectJAutoProxy
+@Configuration
+public class LogicContext implements EnvironmentAware {
+
+    private Environment env;
+
+    @Override
+    public void setEnvironment(final Environment env) {
+        this.env = env;
+    }
+
+    @Bean
+    public String version() {
+        return env.getProperty("version");
+    }
+
+    @Bean
+    public String buildNumber() {
+        return env.getProperty("buildNumber");
+    }
+
+    @Bean
+    public LogicInvocationHandler logicInvocationHandler()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (LogicInvocationHandler) Class.forName(env.getProperty("logicInvocationHandler")).
+                newInstance();
+    }
+
+    @Bean
+    public ImplementationLookup classPathScanImplementationLookup()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (ImplementationLookup) Class.forName(env.getProperty("classPathScanImplementationLookup")).
+                newInstance();
+    }
+}
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
index 7d231f9..befe117 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
@@ -67,6 +67,7 @@ import org.quartz.JobDataMap;
 import org.quartz.JobKey;
 import org.quartz.SchedulerException;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.InvalidDataAccessApiUsageException;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
@@ -191,7 +192,7 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
                     collect(Collectors.toList());
 
             return Pair.of(count, result);
-        } catch (IllegalArgumentException e) {
+        } catch (IllegalArgumentException | InvalidDataAccessApiUsageException e) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRequest);
             sce.getElements().add(e.getMessage());
             throw sce;
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
index e77e09b..79f1c87 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
@@ -89,7 +89,7 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
     private Set<Class<?>> auditAppenderClasses;
 
     @Override
-    public Integer getPriority() {
+    public int getOrder() {
         return Integer.MIN_VALUE;
     }
 
@@ -102,8 +102,8 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
         return DEFAULT_BASE_PACKAGE;
     }
 
-    @Override
     @SuppressWarnings("unchecked")
+    @Override
     public void load() {
         classNames = new EnumMap<>(ImplementationType.class);
         for (ImplementationType type : ImplementationType.values()) {
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java
index 6ca7df1..41716cb 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java
@@ -18,39 +18,35 @@
  */
 package org.apache.syncope.core.logic.init;
 
-import java.util.Map;
 import javax.sql.DataSource;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.apache.syncope.core.persistence.api.DomainsHolder;
-import org.apache.syncope.core.persistence.api.SyncopeLoader;
+import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
-public class EntitlementLoader implements SyncopeLoader {
-
-    @Autowired
-    private DomainsHolder domainsHolder;
+public class EntitlementLoader implements SyncopeCoreLoader {
 
     @Autowired
     private EntitlementAccessor entitlementAccessor;
 
     @Override
-    public Integer getPriority() {
+    public int getOrder() {
         return 900;
     }
 
     @Override
     public void load() {
         EntitlementsHolder.getInstance().init(StandardEntitlement.values());
+    }
 
-        for (Map.Entry<String, DataSource> entry : domainsHolder.getDomains().entrySet()) {
-            AuthContextUtils.execWithAuthContext(entry.getKey(), () -> {
-                entitlementAccessor.addEntitlementsForAnyTypes();
-                return null;
-            });
-        }
+    @Override
+    public void load(final String domain, final DataSource datasource) {
+        AuthContextUtils.execWithAuthContext(domain, () -> {
+            entitlementAccessor.addEntitlementsForAnyTypes();
+            return null;
+        });
     }
 }
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
index c530e49..2903a10 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
@@ -39,9 +39,8 @@ import org.apache.syncope.common.lib.types.AuditLoggerName;
 import org.apache.syncope.core.logic.audit.AuditAppender;
 import org.apache.syncope.core.logic.MemoryAppender;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.ImplementationLookup;
-import org.apache.syncope.core.persistence.api.SyncopeLoader;
+import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -50,10 +49,7 @@ import org.springframework.jdbc.datasource.DataSourceUtils;
 import org.springframework.stereotype.Component;
 
 @Component
-public class LoggerLoader implements SyncopeLoader {
-
-    @Autowired
-    private DomainsHolder domainsHolder;
+public class LoggerLoader implements SyncopeCoreLoader {
 
     @Autowired
     private LoggerAccessor loggerAccessor;
@@ -64,21 +60,11 @@ public class LoggerLoader implements SyncopeLoader {
     private final Map<String, MemoryAppender> memoryAppenders = new HashMap<>();
 
     @Override
-    public Integer getPriority() {
+    public int getOrder() {
         return 300;
     }
 
-    @Override
-    public void load() {
-        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
-
-        ctx.getConfiguration().getAppenders().entrySet().stream().
-                filter(entry -> (entry.getValue() instanceof MemoryAppender)).
-                forEach(entry -> {
-                    memoryAppenders.put(entry.getKey(), (MemoryAppender) entry.getValue());
-                });
-
-        // Audit table and DataSource for each configured domain
+    private ColumnConfig[] buildColumnConfigs(final LoggerContext ctx) {
         ColumnConfig[] columnConfigs = {
             ColumnConfig.newBuilder().
             setConfiguration(ctx.getConfiguration()).setName("EVENT_DATE").setEventTimestamp(true).build(),
@@ -91,33 +77,44 @@ public class LoggerLoader implements SyncopeLoader {
             ColumnConfig.newBuilder().setUnicode(false).
             setConfiguration(ctx.getConfiguration()).setName("THROWABLE").setPattern("%ex{full}").build()
         };
-        ColumnMapping[] columnMappings = new ColumnMapping[0];
-
-        for (Map.Entry<String, DataSource> entry : domainsHolder.getDomains().entrySet()) {
-            Appender appender = ctx.getConfiguration().getAppender("audit_for_" + entry.getKey());
-            if (appender == null) {
-                appender = JdbcAppender.newBuilder().
-                        withName("audit_for_" + entry.getKey()).
-                        withIgnoreExceptions(false).
-                        setConnectionSource(new DataSourceConnectionSource(entry.getKey(), entry.getValue())).
-                        setBufferSize(0).
-                        setTableName("SYNCOPEAUDIT").
-                        setColumnConfigs(columnConfigs).
-                        setColumnMappings(columnMappings).
-                        build();
-                appender.start();
-                ctx.getConfiguration().addAppender(appender);
-            }
 
-            LoggerConfig logConf = new LoggerConfig(AuditLoggerName.getAuditLoggerName(entry.getKey()), null, false);
+        return columnConfigs;
+    }
+
+    @Override
+    public void load(final String domain, final DataSource datasource) {
+        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+
+        ctx.getConfiguration().getAppenders().entrySet().stream().
+                filter(entry -> (entry.getValue() instanceof MemoryAppender)).
+                forEach(entry -> {
+                    memoryAppenders.put(entry.getKey(), (MemoryAppender) entry.getValue());
+                });
+
+        // Audit table and DataSource for the given domain
+        Appender appender = ctx.getConfiguration().getAppender("audit_for_" + domain);
+        if (appender == null) {
+            appender = JdbcAppender.newBuilder().
+                    withName("audit_for_" + domain).
+                    withIgnoreExceptions(false).
+                    setConnectionSource(new DataSourceConnectionSource(domain, datasource)).
+                    setBufferSize(0).
+                    setTableName("SYNCOPEAUDIT").
+                    setColumnConfigs(buildColumnConfigs(ctx)).
+                    setColumnMappings(new ColumnMapping[0]).
+                    build();
+            appender.start();
+            ctx.getConfiguration().addAppender(appender);
+
+            LoggerConfig logConf = new LoggerConfig(AuditLoggerName.getAuditLoggerName(domain), null, false);
             logConf.addAppender(appender, Level.DEBUG, null);
             logConf.setLevel(Level.DEBUG);
             ctx.getConfiguration().addLogger(logConf.getName(), logConf);
 
             // SYNCOPE-1144 For each custom audit appender class add related appenders to log4j logger
-            auditAppenders(entry.getKey()).forEach(auditAppender -> {
+            auditAppenders(domain).forEach(auditAppender -> {
                 auditAppender.getEvents().stream().
-                        map(event -> AuditLoggerName.getAuditEventLoggerName(entry.getKey(), event.toLoggerName())).
+                        map(event -> AuditLoggerName.getAuditEventLoggerName(domain, event.toLoggerName())).
                         forEachOrdered(domainAuditLoggerName -> {
                             LoggerConfig eventLogConf = ctx.getConfiguration().getLoggerConfig(domainAuditLoggerName);
                             boolean isRootLogConf = LogManager.ROOT_LOGGER_NAME.equals(eventLogConf.getName());
@@ -132,7 +129,7 @@ public class LoggerLoader implements SyncopeLoader {
                         });
             });
 
-            AuthContextUtils.execWithAuthContext(entry.getKey(), () -> {
+            AuthContextUtils.execWithAuthContext(domain, () -> {
                 loggerAccessor.synchronizeLog4J(ctx);
                 return null;
             });
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
deleted file mode 100644
index 3e1b1c9..0000000
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
+++ /dev/null
@@ -1,69 +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.core.logic.init;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.apache.syncope.core.spring.ApplicationContextProvider;
-import org.apache.syncope.core.persistence.api.SyncopeLoader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.aop.support.AopUtils;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.stereotype.Component;
-
-/**
- * Take care of all initializations needed by Syncope logic to run up and safe.
- */
-@Component
-public class LogicInitializer implements InitializingBean, BeanFactoryAware {
-
-    private static final Logger LOG = LoggerFactory.getLogger(LogicInitializer.class);
-
-    private DefaultListableBeanFactory beanFactory;
-
-    @Override
-    public void setBeanFactory(final BeanFactory beanFactory) {
-        this.beanFactory = (DefaultListableBeanFactory) beanFactory;
-    }
-
-    @Override
-    public void afterPropertiesSet() throws Exception {
-        Map<String, SyncopeLoader> loaderMap = beanFactory.getBeansOfType(SyncopeLoader.class);
-
-        List<SyncopeLoader> loaders = new ArrayList<>(loaderMap.values());
-        Collections.sort(loaders, (o1, o2) -> o1.getPriority().compareTo(o2.getPriority()));
-
-        ApplicationContextProvider.setBeanFactory(beanFactory);
-
-        LOG.debug("Starting initialization...");
-        loaders.stream().map(loader -> {
-            LOG.debug("Invoking {} with priority {}", AopUtils.getTargetClass(loader).getName(), loader.getPriority());
-            return loader;
-        }).forEachOrdered(loader -> {
-            loader.load();
-        });
-        LOG.debug("Initialization completed");
-    }
-}
diff --git a/fit/core-reference/src/main/resources/logic.properties b/core/idrepo/logic/src/main/resources/META-INF/spring.factories
similarity index 82%
copy from fit/core-reference/src/main/resources/logic.properties
copy to core/idrepo/logic/src/main/resources/META-INF/spring.factories
index 802e7853..eb5b93f 100644
--- a/fit/core-reference/src/main/resources/logic.properties
+++ b/core/idrepo/logic/src/main/resources/META-INF/spring.factories
@@ -14,5 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-logicInvocationHandler=org.apache.syncope.core.logic.LogicInvocationHandler
-classPathScanImplementationLookup=org.apache.syncope.fit.core.reference.ITImplementationLookup
+
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  org.apache.syncope.core.logic.LogicContext
diff --git a/core/idrepo/logic/src/main/resources/logic.properties b/core/idrepo/logic/src/main/resources/logic.properties
index a9a71b1..8256e4b 100644
--- a/core/idrepo/logic/src/main/resources/logic.properties
+++ b/core/idrepo/logic/src/main/resources/logic.properties
@@ -14,5 +14,7 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+version=${syncope.version}
+buildNumber=${buildNumber}
 logicInvocationHandler=org.apache.syncope.core.logic.LogicInvocationHandler
 classPathScanImplementationLookup=org.apache.syncope.core.logic.init.ClassPathScanImplementationLookup
diff --git a/core/idrepo/logic/src/main/resources/logicContext.xml b/core/idrepo/logic/src/main/resources/logicContext.xml
deleted file mode 100644
index 59066a9..0000000
--- a/core/idrepo/logic/src/main/resources/logicContext.xml
+++ /dev/null
@@ -1,46 +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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:aop="http://www.springframework.org/schema/aop"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                           http://www.springframework.org/schema/beans/spring-beans.xsd
-                           http://www.springframework.org/schema/aop 
-                           http://www.springframework.org/schema/aop/spring-aop.xsd
-                           http://www.springframework.org/schema/context
-                           http://www.springframework.org/schema/context/spring-context.xsd">
-  
-  <bean id="version" class="java.lang.String">
-    <constructor-arg value="${syncope.version}"/>
-  </bean>
-  <bean id="buildNumber" class="java.lang.String">
-    <constructor-arg value="${buildNumber}"/>
-  </bean>
-
-  <aop:aspectj-autoproxy/>
-
-  <context:component-scan base-package="org.apache.syncope.core.logic"/>
-
-  <bean class="${logicInvocationHandler}"/>
-
-  <bean class="${classPathScanImplementationLookup}"/>
-
-</beans>
diff --git a/core/idrepo/rest-cxf/pom.xml b/core/idrepo/rest-cxf/pom.xml
index 96bb398..36d55c1 100644
--- a/core/idrepo/rest-cxf/pom.xml
+++ b/core/idrepo/rest-cxf/pom.xml
@@ -50,26 +50,15 @@ under the License.
     </dependency>
 
     <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-context</artifactId>
-    </dependency>    
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-orm</artifactId>
-    </dependency>      
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-web</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-web</artifactId>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot</artifactId>
     </dependency>
+
     <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-config</artifactId>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-webmvc</artifactId>
     </dependency>
-    
+
     <dependency>
       <groupId>com.fasterxml.jackson.datatype</groupId>
       <artifactId>jackson-datatype-joda</artifactId>
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/JavaDocUtils.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/JavaDocUtils.java
index f4ab5c5..04d62a2 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/JavaDocUtils.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/JavaDocUtils.java
@@ -23,6 +23,7 @@ import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.core.env.Environment;
 import org.springframework.util.ClassUtils;
 
 public final class JavaDocUtils {
@@ -47,6 +48,16 @@ public final class JavaDocUtils {
         return result;
     }
 
+    public static String[] getJavaDocPaths(final Environment env) {
+        String[] result = null;
+
+        if (env.containsProperty("javadocPaths")) {
+            result = env.getProperty("javadocPaths").split(",");
+        }
+
+        return result;
+    }
+
     private JavaDocUtils() {
         // private constructor for static utility class
     }
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RESTCXFContext.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RESTCXFContext.java
new file mode 100644
index 0000000..92d5f44
--- /dev/null
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RESTCXFContext.java
@@ -0,0 +1,39 @@
+/*
+ * 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.core.rest.cxf;
+
+import javax.servlet.ServletRequestListener;
+import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.ImportResource;
+
+@ImportResource("classpath:/restCXFContext.xml")
+@ComponentScan("org.apache.syncope.core.rest.cxf.service")
+@Configuration
+public class RESTCXFContext {
+
+    @Bean
+    public ServletListenerRegistrationBean<ServletRequestListener> listenerRegistrationBean() {
+        ServletListenerRegistrationBean<ServletRequestListener> bean = new ServletListenerRegistrationBean<>();
+        bean.setListener(new ThreadLocalCleanupListener());
+        return bean;
+    }
+}
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
index acf5c3b..40da849 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
@@ -60,7 +60,7 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.PropertySource;
 import org.springframework.core.env.Environment;
 import org.springframework.dao.DataIntegrityViolationException;
-import org.springframework.orm.jpa.JpaSystemException;
+import org.springframework.dao.UncategorizedDataAccessException;
 import org.springframework.security.access.AccessDeniedException;
 import org.springframework.transaction.TransactionSystemException;
 
@@ -111,7 +111,7 @@ public class RestServiceExceptionMapper implements ExceptionMapper<Exception> {
 
             builder = builder(ClientExceptionType.EntityExists,
                     getPersistenceErrorMessage(ex instanceof PersistenceException ? ex.getCause() : ex));
-        } else if (ex instanceof DataIntegrityViolationException || ex instanceof JpaSystemException) {
+        } else if (ex instanceof DataIntegrityViolationException || ex instanceof UncategorizedDataAccessException) {
             builder = builder(ClientExceptionType.DataIntegrityViolation, getPersistenceErrorMessage(ex));
         } else if (ex instanceof ConnectorException) {
             builder = builder(ClientExceptionType.ConnectorException, ExceptionUtils.getRootCauseMessage(ex));
@@ -259,7 +259,7 @@ public class RestServiceExceptionMapper implements ExceptionMapper<Exception> {
             return builder(ClientExceptionType.GenericPersistence, ExceptionUtils.getRootCauseMessage(ex));
         } else if (ibatisPersistenceException != null && ibatisPersistenceException.isAssignableFrom(ex.getClass())) {
             return builder(ClientExceptionType.Workflow, "Currently unavailable. Please try later.");
-        } else if (ex instanceof JpaSystemException) {
+        } else if (ex instanceof UncategorizedDataAccessException) {
             return builder(ClientExceptionType.DataIntegrityViolation, ExceptionUtils.getRootCauseMessage(ex));
         } else if (ex instanceof ConfigurationException) {
             return builder(ClientExceptionType.InvalidConnIdConf, ExceptionUtils.getRootCauseMessage(ex));
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/SyncopeOpenApiCustomizer.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/SyncopeOpenApiCustomizer.java
index 2676521..4ad981c 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/SyncopeOpenApiCustomizer.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/SyncopeOpenApiCustomizer.java
@@ -31,6 +31,7 @@ import io.swagger.v3.oas.models.responses.ApiResponses;
 import io.swagger.v3.oas.models.servers.Server;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -39,7 +40,6 @@ import java.util.Optional;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.model.OperationResourceInfo;
-import org.apache.cxf.jaxrs.model.doc.JavaDocProvider;
 import org.apache.cxf.jaxrs.openapi.OpenApiCustomizer;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
@@ -47,25 +47,51 @@ import org.apache.syncope.common.lib.to.ErrorTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.core.env.Environment;
 
-public class SyncopeOpenApiCustomizer extends OpenApiCustomizer {
+public class SyncopeOpenApiCustomizer extends OpenApiCustomizer implements EnvironmentAware {
 
-    private JavaDocProvider javadocProvider;
+    private static final Logger LOG = LoggerFactory.getLogger(WadlGenerator.class);
+
+    private Environment env;
+
+    private boolean inited = false;
 
     private List<String> domains;
 
-    public SyncopeOpenApiCustomizer() {
-        super();
+    @Override
+    public void setEnvironment(final Environment env) {
+        this.env = env;
+    }
 
-        URL[] javaDocURLs = JavaDocUtils.getJavaDocURLs();
-        if (javaDocURLs != null) {
-            this.javadocProvider = new JavaDocProvider(javaDocURLs);
-            super.setJavadocProvider(javadocProvider);
+    private void init() {
+        synchronized (this) {
+            if (!inited) {
+                URL[] javaDocURLs = JavaDocUtils.getJavaDocURLs();
+                if (javaDocURLs == null) {
+                    String[] javaDocPaths = JavaDocUtils.getJavaDocPaths(env);
+                    if (javaDocPaths != null) {
+                        try {
+                            super.setJavaDocPaths(javaDocPaths);
+                        } catch (Exception e) {
+                            LOG.error("Could not set javadoc paths from {}", Arrays.asList(javaDocPaths), e);
+                        }
+                    }
+                } else {
+                    super.setJavaDocURLs(javaDocURLs);
+                }
+
+                inited = true;
+            }
         }
     }
 
     @Override
     public OpenAPIConfiguration customize(final OpenAPIConfiguration configuration) {
+        init();
         super.customize(configuration);
 
         MessageContext ctx = JAXRSUtils.createContextValue(
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WADLInitializer.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WADLInitializer.java
new file mode 100644
index 0000000..89173b0
--- /dev/null
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WADLInitializer.java
@@ -0,0 +1,42 @@
+/*
+ * 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.core.rest.cxf;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+import org.springframework.boot.web.servlet.ServletContextInitializer;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WADLInitializer implements WebMvcConfigurer, ServletContextInitializer {
+
+    @Override
+    public void addViewControllers(final ViewControllerRegistry registry) {
+        registry.addViewController("/").setViewName("forward:/index.html");
+    }
+
+    @Override
+    public void onStartup(final ServletContext sc) throws ServletException {
+        ServletRegistration.Dynamic wadlServlet = sc.addServlet("WADLServlet", WADLServlet.class);
+        wadlServlet.addMapping("/index.html", "/schema_1_syncope30.html", "/syncope.wadl");
+    }
+}
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WADLServlet.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WADLServlet.java
index c7191da..fe403e4 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WADLServlet.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WADLServlet.java
@@ -39,6 +39,7 @@ import org.apache.cocoon.sax.component.XMLGenerator;
 import org.apache.cocoon.sax.component.XMLSerializer;
 import org.apache.cocoon.sax.component.XSLTTransformer;
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 
 public class WADLServlet extends HttpServlet {
@@ -78,7 +79,7 @@ public class WADLServlet extends HttpServlet {
 
         Pipeline<SAXPipelineComponent> pipeline = new CachingPipeline<>();
         pipeline.addComponent(new XMLGenerator(wadl));
-        if ("/index.html".equals(request.getServletPath())) {
+        if (StringUtils.isEmpty(request.getServletPath()) || "/index.html".equals(request.getServletPath())) {
             XSLTTransformer xslt = new XSLTTransformer(getClass().getResource("/wadl2html/index.xsl"));
 
             Map<String, Object> parameters = new HashMap<>();
@@ -112,5 +113,4 @@ public class WADLServlet extends HttpServlet {
             throw new ServerException("URL not supported: " + request.getRequestURI());
         }
     }
-
 }
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WadlGenerator.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WadlGenerator.java
index 2ea790f..94b23ff 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WadlGenerator.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WadlGenerator.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.rest.cxf;
 import java.lang.annotation.Annotation;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -32,21 +33,43 @@ import org.apache.cxf.common.util.ClasspathScanner;
 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
 import org.apache.cxf.jaxrs.utils.InjectionUtils;
 import org.apache.cxf.jaxrs.utils.ResourceUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.core.env.Environment;
 
 /**
  * Automatically loads available javadocs from class loader (when {@link java.net.URLClassLoader}).
  */
-public class WadlGenerator extends org.apache.cxf.jaxrs.model.wadl.WadlGenerator {
+public class WadlGenerator extends org.apache.cxf.jaxrs.model.wadl.WadlGenerator implements EnvironmentAware {
+
+    private static final Logger LOG = LoggerFactory.getLogger(WadlGenerator.class);
+
+    private Environment env;
 
     private boolean inited = false;
 
     private String wadl = null;
 
+    @Override
+    public void setEnvironment(final Environment env) {
+        this.env = env;
+    }
+
     private void init() {
         synchronized (this) {
             if (!inited) {
                 URL[] javaDocURLs = JavaDocUtils.getJavaDocURLs();
-                if (javaDocURLs != null) {
+                if (javaDocURLs == null) {
+                    String[] javaDocPaths = JavaDocUtils.getJavaDocPaths(env);
+                    if (javaDocPaths != null) {
+                        try {
+                            super.setJavaDocPaths(javaDocPaths);
+                        } catch (Exception e) {
+                            LOG.error("Could not set javadoc paths from {}", Arrays.asList(javaDocPaths), e);
+                        }
+                    }
+                } else {
                     super.setJavaDocURLs(javaDocURLs);
                 }
 
diff --git a/fit/core-reference/src/main/resources/logic.properties b/core/idrepo/rest-cxf/src/main/resources/META-INF/spring.factories
similarity index 82%
copy from fit/core-reference/src/main/resources/logic.properties
copy to core/idrepo/rest-cxf/src/main/resources/META-INF/spring.factories
index 802e7853..27c95ce 100644
--- a/fit/core-reference/src/main/resources/logic.properties
+++ b/core/idrepo/rest-cxf/src/main/resources/META-INF/spring.factories
@@ -14,5 +14,7 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-logicInvocationHandler=org.apache.syncope.core.logic.LogicInvocationHandler
-classPathScanImplementationLookup=org.apache.syncope.fit.core.reference.ITImplementationLookup
+
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  org.apache.syncope.core.rest.cxf.RESTCXFContext,\
+  org.apache.syncope.core.rest.cxf.WADLInitializer
diff --git a/core/idrepo/rest-cxf/src/main/resources/META-INF/web-fragment.xml b/core/idrepo/rest-cxf/src/main/resources/META-INF/web-fragment.xml
deleted file mode 100644
index b0062a4..0000000
--- a/core/idrepo/rest-cxf/src/main/resources/META-INF/web-fragment.xml
+++ /dev/null
@@ -1,82 +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.
--->
-<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee"
-              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
-                                  http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
-              id="${pom.artifactId}" version="3.1">
-  
-  <listener>
-    <listener-class>org.apache.syncope.core.rest.cxf.ThreadLocalCleanupListener</listener-class>
-  </listener>
-  
-  <servlet>
-    <servlet-name>CXFServlet</servlet-name>
-    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
-    <init-param>
-      <param-name>openapi.context.id</param-name>
-      <param-value>openapi.context.id.default</param-value>
-    </init-param>
-    <load-on-startup>1</load-on-startup>
-  </servlet>
-  <servlet-mapping>
-    <servlet-name>CXFServlet</servlet-name>
-    <url-pattern>/rest/*</url-pattern>
-  </servlet-mapping>
-
-  <servlet>
-    <servlet-name>WADLServlet</servlet-name>
-    <servlet-class>org.apache.syncope.core.rest.cxf.WADLServlet</servlet-class>
-    <load-on-startup>2</load-on-startup> 
-  </servlet>
-  <servlet-mapping>
-    <servlet-name>WADLServlet</servlet-name>
-    <url-pattern>/index.html</url-pattern>
-    <url-pattern>/schema_1_syncope30.html</url-pattern>
-    <url-pattern>/syncope.wadl</url-pattern>
-  </servlet-mapping>
-
-  <filter>
-    <filter-name>encodingFilter</filter-name>
-    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
-    <init-param>
-      <param-name>encoding</param-name>
-      <param-value>UTF-8</param-value>
-    </init-param>
-    <init-param>
-      <param-name>forceEncoding</param-name>
-      <param-value>true</param-value>
-    </init-param>
-  </filter>
-  <filter>
-    <filter-name>springSecurityFilterChain</filter-name>
-    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
-  </filter>
-
-  <filter-mapping>
-    <filter-name>encodingFilter</filter-name>
-    <url-pattern>/*</url-pattern>
-  </filter-mapping>
-  <filter-mapping>
-    <filter-name>springSecurityFilterChain</filter-name>
-    <url-pattern>/*</url-pattern>
-  </filter-mapping>
-
-</web-fragment>
diff --git a/core/idrepo/rest-cxf/src/main/resources/restCXFContext.xml b/core/idrepo/rest-cxf/src/main/resources/restCXFContext.xml
index 11e97d8..d6d6350 100644
--- a/core/idrepo/rest-cxf/src/main/resources/restCXFContext.xml
+++ b/core/idrepo/rest-cxf/src/main/resources/restCXFContext.xml
@@ -20,22 +20,14 @@ under the License.
 <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jaxrs="http://cxf.apache.org/jaxrs"
-       xmlns:context="http://www.springframework.org/schema/context"
        xmlns:task="http://www.springframework.org/schema/task"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://cxf.apache.org/jaxrs
                            http://cxf.apache.org/schemas/jaxrs.xsd
-                           http://www.springframework.org/schema/context
-                           http://www.springframework.org/schema/context/spring-context.xsd
                            http://www.springframework.org/schema/task
                            http://www.springframework.org/schema/task/spring-task.xsd">
 
-  <import resource="classpath:META-INF/cxf/cxf.xml"/>
-  <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
-
-  <context:component-scan base-package="org.apache.syncope.core.rest.cxf.service"/>  
-
   <task:executor id="batchExecutor" pool-size="10"/>
 
   <bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
diff --git a/core/persistence-api/pom.xml b/core/persistence-api/pom.xml
index 949b767..0ed3061 100644
--- a/core/persistence-api/pom.xml
+++ b/core/persistence-api/pom.xml
@@ -42,7 +42,12 @@ under the License.
       <groupId>javax.validation</groupId>
       <artifactId>validation-api</artifactId>
     </dependency>
-      
+
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-core</artifactId>
+    </dependency>
+
     <dependency>
       <groupId>net.tirasa.connid</groupId>
       <artifactId>connector-framework</artifactId>
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
index 4488568..7893946 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
@@ -31,7 +31,7 @@ import org.apache.syncope.core.persistence.api.dao.PullCorrelationRule;
 import org.apache.syncope.core.persistence.api.dao.PushCorrelationRule;
 import org.apache.syncope.core.persistence.api.dao.Reportlet;
 
-public interface ImplementationLookup extends SyncopeLoader {
+public interface ImplementationLookup extends SyncopeCoreLoader {
 
     Set<String> getClassNames(ImplementationType type);
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/SyncopeLoader.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/SyncopeCoreLoader.java
similarity index 62%
copy from core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/SyncopeLoader.java
copy to core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/SyncopeCoreLoader.java
index be0caed..a5debbb 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/SyncopeLoader.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/SyncopeCoreLoader.java
@@ -18,18 +18,25 @@
  */
 package org.apache.syncope.core.persistence.api;
 
-/**
- * Marker interface for Syncope components initialization.
- */
-public interface SyncopeLoader {
+import javax.sql.DataSource;
+import org.springframework.core.Ordered;
+
+public interface SyncopeCoreLoader extends Ordered {
 
     /**
-     * @return the priority that the implementing class has in the initialization process.
+     * Perform generic (not related to any domain) initialization operations.
      */
-    Integer getPriority();
+    default void load() {
+        // nothing to do
+    }
 
     /**
-     * Perform initialization operations.
+     * Perform initialization operations on the given domain.
+     *
+     * @param domain domain to initialize
+     * @param datasource db access for the given domain
      */
-    void load();
+    default void load(String domain, DataSource datasource) {
+        // nothing to do        
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentLoader.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentDealer.java
similarity index 88%
copy from core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentLoader.java
copy to core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentDealer.java
index 67435fa..442d3ef 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentLoader.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentDealer.java
@@ -18,8 +18,8 @@
  */
 package org.apache.syncope.core.persistence.api.content;
 
-import org.apache.syncope.core.persistence.api.SyncopeLoader;
+public interface ContentDealer {
 
-public interface ContentLoader extends SyncopeLoader {
+    String ROOT_ELEMENT = "dataset";
 
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java
index 4b2cf10..abf58ea 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java
@@ -22,8 +22,13 @@ import java.io.OutputStream;
 import javax.xml.transform.TransformerConfigurationException;
 import org.xml.sax.SAXException;
 
-public interface ContentExporter {
+public interface ContentExporter extends ContentDealer {
 
-    void export(String domain, OutputStream output, String uwfPrefix, String gwfPrefix, String awfPrefix) 
+    void export(
+            String domain,
+            OutputStream output,
+            String uwfPrefix,
+            String gwfPrefix,
+            String awfPrefix)
             throws SAXException, TransformerConfigurationException;
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentLoader.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentLoader.java
index 67435fa..61276ac 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentLoader.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentLoader.java
@@ -18,8 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.content;
 
-import org.apache.syncope.core.persistence.api.SyncopeLoader;
-
-public interface ContentLoader extends SyncopeLoader {
+import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
 
+public interface ContentLoader extends SyncopeCoreLoader, ContentDealer {
 }
diff --git a/core/persistence-jpa-json/pom.xml b/core/persistence-jpa-json/pom.xml
index e8e1e9a..911446e 100644
--- a/core/persistence-jpa-json/pom.xml
+++ b/core/persistence-jpa-json/pom.xml
@@ -197,6 +197,10 @@ under the License.
                     <ports>
                       <port>5432:5432</port>
                     </ports>
+                    <wait>
+                      <log>database system is ready to accept connections</log>
+                      <time>30000</time>
+                    </wait>
                   </run>
                 </image>
               </images>
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/DomainConfFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/DomainConfFactory.java
new file mode 100644
index 0000000..1da8122
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/DomainConfFactory.java
@@ -0,0 +1,153 @@
+/*
+ * 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.core.persistence.jpa;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import javax.sql.DataSource;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.request.DomainCR;
+import org.apache.syncope.core.persistence.jpa.spring.DomainEntityManagerFactoryBean;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ResourceWithFallbackLoader;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.AutowireCandidateQualifier;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.jdbc.datasource.init.DataSourceInitializer;
+import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
+import org.springframework.jndi.JndiObjectFactoryBean;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DomainConfFactory implements EnvironmentAware {
+
+    @Value("${content.directory}")
+    private String contentDirectory;
+
+    private Environment env;
+
+    @Override
+    public void setEnvironment(final Environment env) {
+        this.env = env;
+    }
+
+    private void registerSingleton(final String name, final Object bean) {
+        if (ApplicationContextProvider.getBeanFactory().containsSingleton(name)) {
+            ApplicationContextProvider.getBeanFactory().destroySingleton(name);
+        }
+        ApplicationContextProvider.getBeanFactory().registerSingleton(name, bean);
+    }
+
+    private void registerBeanDefinition(final String name, final BeanDefinition beanDefinition) {
+        if (ApplicationContextProvider.getBeanFactory().containsBeanDefinition(name)) {
+            ApplicationContextProvider.getBeanFactory().removeBeanDefinition(name);
+        }
+        ApplicationContextProvider.getBeanFactory().registerBeanDefinition(name, beanDefinition);
+    }
+
+    public void register(final DomainCR req) {
+        // localDomainDataSource
+        HikariConfig hikariConfig = new HikariConfig();
+        hikariConfig.setDriverClassName(req.getJdbcDriver());
+        hikariConfig.setJdbcUrl(req.getJdbcURL());
+        hikariConfig.setUsername(req.getDbUsername());
+        hikariConfig.setPassword(req.getDbPassword());
+        hikariConfig.setSchema(req.getDbSchema());
+        hikariConfig.setTransactionIsolation(req.getTransactionIsolation());
+        hikariConfig.setMaximumPoolSize(req.getMaxPoolSize());
+        hikariConfig.setMinimumIdle(req.getMinIdle());
+        String domainName = StringUtils.capitalize(req.getDomainName());
+
+        HikariDataSource localDomainDataSource = new HikariDataSource(hikariConfig);
+
+        // domainDataSource
+        registerBeanDefinition(
+                domainName + "DataSource",
+                BeanDefinitionBuilder.rootBeanDefinition(JndiObjectFactoryBean.class).
+                        addPropertyValue("jndiName", "java:comp/env/jdbc/syncope" + domainName + "DataSource").
+                        addPropertyValue("defaultObject", localDomainDataSource).
+                        getBeanDefinition());
+        DataSource initedDataSource = ApplicationContextProvider.getBeanFactory().
+                getBean(domainName + "DataSource", DataSource.class);
+
+        // domainResourceDatabasePopulator
+        ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
+        databasePopulator.setContinueOnError(true);
+        databasePopulator.setIgnoreFailedDrops(true);
+        databasePopulator.setSqlScriptEncoding(StandardCharsets.UTF_8.name());
+        databasePopulator.addScript(new ClassPathResource("/audit/" + req.getAuditSql()));
+
+        registerSingleton(domainName.toLowerCase() + "ResourceDatabasePopulator", databasePopulator);
+
+        // domainDataSourceInitializer
+        DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
+        dataSourceInitializer.setDataSource(initedDataSource);
+        dataSourceInitializer.setEnabled(true);
+        dataSourceInitializer.setDatabasePopulator(databasePopulator);
+        registerSingleton(domainName.toLowerCase() + "DataSourceInitializer", dataSourceInitializer);
+
+        // domainEntityManagerFactory
+        OpenJpaVendorAdapter vendorAdapter = new OpenJpaVendorAdapter();
+        vendorAdapter.setShowSql(false);
+        vendorAdapter.setGenerateDdl(true);
+        vendorAdapter.setDatabasePlatform(req.getDatabasePlatform());
+
+        BeanDefinitionBuilder emf = BeanDefinitionBuilder.rootBeanDefinition(DomainEntityManagerFactoryBean.class).
+                addPropertyValue("mappingResources", req.getOrm()).
+                addPropertyValue("persistenceUnitName", domainName).
+                addPropertyReference("dataSource", domainName + "DataSource").
+                addPropertyValue("jpaVendorAdapter", vendorAdapter).
+                addPropertyReference("commonEntityManagerFactoryConf", "commonEMFConf");
+        if (env.containsProperty("openjpaMetaDataFactory")) {
+            emf.addPropertyValue("jpaPropertyMap",
+                    Collections.singletonMap(
+                            "openjpa.MetaDataFactory",
+                            env.getProperty("openjpaMetaDataFactory").replace("##orm##", req.getOrm())));
+        }
+        registerBeanDefinition(domainName + "EntityManagerFactory", emf.getBeanDefinition());
+        ApplicationContextProvider.getBeanFactory().getBean(domainName + "EntityManagerFactory");
+
+        // domainTransactionManager
+        AbstractBeanDefinition domainTransactionManager =
+                BeanDefinitionBuilder.rootBeanDefinition(JpaTransactionManager.class).
+                        addPropertyReference("entityManagerFactory", domainName + "EntityManagerFactory").
+                        getBeanDefinition();
+        domainTransactionManager.addQualifier(new AutowireCandidateQualifier(Qualifier.class, domainName));
+        registerBeanDefinition(domainName + "TransactionManager", domainTransactionManager);
+
+        // domainContentXML
+        registerBeanDefinition(domainName + "ContentXML",
+                BeanDefinitionBuilder.rootBeanDefinition(ResourceWithFallbackLoader.class)
+                        .addPropertyValue(
+                                "primary", "file:" + contentDirectory + "/domains/" + domainName + "Content.xml")
+                        .addPropertyValue(
+                                "fallback", "classpath:domains/" + domainName + "Content.xml")
+                        .getBeanDefinition());
+    }
+}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/DomainLoader.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/DomainLoader.java
new file mode 100644
index 0000000..277bebc
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/DomainLoader.java
@@ -0,0 +1,105 @@
+/*
+ * 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.core.persistence.jpa;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Properties;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.PropertyUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.request.DomainCR;
+import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.Ordered;
+import org.springframework.core.io.Resource;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DomainLoader implements SyncopeCoreLoader {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DomainLoader.class);
+
+    @Autowired
+    private ApplicationContext ctx;
+
+    @Autowired
+    private DomainConfFactory domainConfFactory;
+
+    @Value("${content.directory}")
+    private String contentDirectory;
+
+    @Override
+    public int getOrder() {
+        return Ordered.HIGHEST_PRECEDENCE;
+    }
+
+    @Override
+    public void load() {
+        try {
+            for (Resource domainProp : ctx.getResources("classpath:/domains/*.properties")) {
+                String domainPropFile = StringUtils.substringAfterLast(domainProp.getURL().toExternalForm(), "/");
+                String domain = StringUtils.substringBefore(domainPropFile, ".");
+
+                if (!SyncopeConstants.MASTER_DOMAIN.equals(domain)) {
+                    DomainCR.Builder builder = new DomainCR.Builder(domain);
+
+                    LOG.info("Domain {} initialization", domain);
+
+                    Properties props = PropertyUtils.read(getClass(), "domains/" + domainPropFile, contentDirectory);
+                    for (Enumeration<?> e = props.propertyNames(); e.hasMoreElements();) {
+                        String prop = (String) e.nextElement();
+
+                        if (prop.endsWith(".driverClassName")) {
+                            builder.jdbcDriver(props.getProperty(prop));
+                        } else if (prop.endsWith(".url")) {
+                            builder.jdbcURL(props.getProperty(prop));
+                        } else if (prop.endsWith(".schema")) {
+                            builder.dbSchema(props.getProperty(prop));
+                        } else if (prop.endsWith(".username")) {
+                            builder.dbUsername(props.getProperty(prop));
+                        } else if (prop.endsWith(".password")) {
+                            builder.dbPassword(props.getProperty(prop));
+                        } else if (prop.endsWith(".databasePlatform")) {
+                            builder.databasePlatform(props.getProperty(prop));
+                        } else if (prop.endsWith(".orm")) {
+                            builder.orm(props.getProperty(prop));
+                        } else if (prop.endsWith(".pool.maxActive")) {
+                            builder.maxPoolSize(Integer.parseInt(props.getProperty(prop)));
+                        } else if (prop.endsWith(".pool.minIdle")) {
+                            builder.minIdle(Integer.parseInt(props.getProperty(prop)));
+                        } else if (prop.endsWith(".audit.sql")) {
+                            builder.auditSql(props.getProperty(prop));
+                        }
+                    }
+
+                    domainConfFactory.register(builder.build());
+
+                    LOG.info("Domain {} successfully inited", domain);
+                }
+            }
+        } catch (IOException e) {
+            LOG.error("Error during domain initialization", e);
+        }
+    }
+}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MasterDomain.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MasterDomain.java
new file mode 100644
index 0000000..76a0fb7
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MasterDomain.java
@@ -0,0 +1,184 @@
+/*
+ * 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.core.persistence.jpa;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import java.util.Collections;
+import javax.sql.DataSource;
+import org.apache.syncope.core.persistence.jpa.spring.CommonEntityManagerFactoryConf;
+import org.apache.syncope.core.persistence.jpa.spring.DomainEntityManagerFactoryBean;
+import org.apache.syncope.core.spring.ResourceWithFallbackLoader;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.Resource;
+import org.springframework.jdbc.datasource.init.DataSourceInitializer;
+import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
+import org.springframework.jndi.JndiObjectFactoryBean;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter;
+import org.springframework.transaction.PlatformTransactionManager;
+
+@PropertySource("classpath:domains/Master.properties")
+@PropertySource(value = "file:${conf.directory}/domains/Master.properties", ignoreResourceNotFound = true)
+@Configuration
+public class MasterDomain implements EnvironmentAware {
+
+    private Environment env;
+
+    @Autowired
+    private CommonEntityManagerFactoryConf commonEMFConf;
+
+    @Value("${Master.driverClassName}")
+    private String driverClassName;
+
+    @Value("${Master.url}")
+    private String url;
+
+    @Value("${Master.schema}")
+    private String schema;
+
+    @Value("${Master.username}")
+    private String username;
+
+    @Value("${Master.password}")
+    private String password;
+
+    @Value("${Master.pool.transactionIsolation:TRANSACTION_READ_COMMITTED}")
+    private String transactionIsolation;
+
+    @Value("${Master.pool.maxActive:10}")
+    private int maximumPoolSize;
+
+    @Value("${Master.pool.minIdle:2}")
+    private int minimumIdle;
+
+    @Value("classpath:/audit/${Master.audit.sql}")
+    private Resource auditSql;
+
+    @Value("${Master.orm}")
+    private String orm;
+
+    @Value("${Master.databasePlatform}")
+    private String databasePlatform;
+
+    @Value("${content.directory}")
+    private String contentDirectory;
+
+    @Override
+    public void setEnvironment(final Environment env) {
+        this.env = env;
+    }
+
+    public DataSource localMasterDataSource() {
+        HikariConfig hikariConfig = new HikariConfig();
+        hikariConfig.setDriverClassName(driverClassName);
+        hikariConfig.setJdbcUrl(url);
+        hikariConfig.setUsername(username);
+        hikariConfig.setPassword(password);
+        hikariConfig.setTransactionIsolation(transactionIsolation);
+        hikariConfig.setMaximumPoolSize(maximumPoolSize);
+        hikariConfig.setMinimumIdle(minimumIdle);
+        return new HikariDataSource(hikariConfig);
+    }
+
+    @Bean("MasterDataSource")
+    public JndiObjectFactoryBean masterDataSource() {
+        JndiObjectFactoryBean masterDataSource = new JndiObjectFactoryBean();
+        masterDataSource.setJndiName("java:comp/env/jdbc/syncopeMasterDataSource");
+        masterDataSource.setDefaultObject(localMasterDataSource());
+        return masterDataSource;
+    }
+
+    @Bean
+    public ResourceDatabasePopulator masterResourceDatabasePopulator() {
+        ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
+        databasePopulator.setContinueOnError(true);
+        databasePopulator.setIgnoreFailedDrops(true);
+        databasePopulator.setSqlScriptEncoding("UTF-8");
+        databasePopulator.addScript(auditSql);
+        return databasePopulator;
+    }
+
+    @Bean
+    public DataSourceInitializer masterDataSourceInitializer() {
+        DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
+        dataSourceInitializer.setDataSource((DataSource) masterDataSource().getObject());
+        dataSourceInitializer.setEnabled(true);
+        dataSourceInitializer.setDatabasePopulator(masterResourceDatabasePopulator());
+        return dataSourceInitializer;
+    }
+
+    @Bean("MasterEntityManagerFactory")
+    @DependsOn("commonEMFConf")
+    public DomainEntityManagerFactoryBean masterEntityManagerFactory() {
+        OpenJpaVendorAdapter vendorAdapter = new OpenJpaVendorAdapter();
+        vendorAdapter.setShowSql(false);
+        vendorAdapter.setGenerateDdl(true);
+        vendorAdapter.setDatabasePlatform(databasePlatform);
+        DomainEntityManagerFactoryBean masterEntityManagerFactory = new DomainEntityManagerFactoryBean();
+        masterEntityManagerFactory.setMappingResources(orm);
+        masterEntityManagerFactory.setPersistenceUnitName("Master");
+        masterEntityManagerFactory.setDataSource((DataSource) masterDataSource().getObject());
+        masterEntityManagerFactory.setJpaVendorAdapter(vendorAdapter);
+        masterEntityManagerFactory.setCommonEntityManagerFactoryConf(commonEMFConf);
+
+        if (env.containsProperty("openjpaMetaDataFactory")) {
+            masterEntityManagerFactory.setJpaPropertyMap(Collections.singletonMap(
+                    "openjpa.MetaDataFactory",
+                    env.getProperty("openjpaMetaDataFactory").replace("##orm##", orm)));
+        }
+
+        return masterEntityManagerFactory;
+    }
+
+    @Bean("MasterTransactionManager")
+    @Qualifier("Master")
+    public PlatformTransactionManager transactionManager() {
+        return new JpaTransactionManager(masterEntityManagerFactory().getObject());
+    }
+
+    @Bean("MasterProperties")
+    public ResourceWithFallbackLoader masterProperties() {
+        ResourceWithFallbackLoader masterProperties = new ResourceWithFallbackLoader();
+        masterProperties.setPrimary("file:" + contentDirectory + "/domains/Master.properties");
+        masterProperties.setFallback("classpath:domains/Master.properties");
+        return masterProperties;
+    }
+
+    @Bean("MasterContentXML")
+    public ResourceWithFallbackLoader masterContentXML() {
+        ResourceWithFallbackLoader masterContentXML = new ResourceWithFallbackLoader();
+        masterContentXML.setPrimary("file:" + contentDirectory + "/domains/MasterContent.xml");
+        masterContentXML.setFallback("classpath:domains/MasterContent.xml");
+        return masterContentXML;
+    }
+
+    @Bean("MasterDatabaseSchema")
+    public String masterDatabaseSchema() {
+        return schema;
+    }
+}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
new file mode 100644
index 0000000..d732fbd
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
@@ -0,0 +1,186 @@
+/*
+ * 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.core.persistence.jpa;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.ValidationMode;
+import javax.validation.Validator;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.ConfDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.jpa.spring.CommonEntityManagerFactoryConf;
+import org.apache.syncope.core.persistence.jpa.spring.DomainTransactionInterceptorInjector;
+import org.apache.syncope.core.persistence.jpa.spring.MultiJarAwarePersistenceUnitPostProcessor;
+import org.apache.syncope.core.spring.ResourceWithFallbackLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
+
+@PropertySource("classpath:persistence.properties")
+@PropertySource(value = "file:${conf.directory}/persistence.properties", ignoreResourceNotFound = true)
+@ComponentScan("org.apache.syncope.core.persistence.jpa")
+@Configuration
+public class PersistenceContext implements EnvironmentAware {
+
+    private static final Logger OPENJPA_LOG = LoggerFactory.getLogger("org.apache.openjpa");
+
+    private Environment env;
+
+    @Override
+    public void setEnvironment(final Environment env) {
+        this.env = env;
+    }
+
+    @Bean
+    public static BeanFactoryPostProcessor domainTransactionInterceptorInjector() {
+        return new DomainTransactionInterceptorInjector();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public CommonEntityManagerFactoryConf commonEMFConf() {
+        CommonEntityManagerFactoryConf commonEMFConf = new CommonEntityManagerFactoryConf();
+        commonEMFConf.setPackagesToScan("org.apache.syncope.core.persistence.jpa.entity");
+        commonEMFConf.setValidationMode(ValidationMode.NONE);
+        commonEMFConf.setPersistenceUnitPostProcessors(new MultiJarAwarePersistenceUnitPostProcessor());
+        Map<String, Object> jpaPropertyMap = new HashMap<>();
+
+        jpaPropertyMap.put("openjpa.Log", "slf4j");
+        if (OPENJPA_LOG.isDebugEnabled()) {
+            jpaPropertyMap.put("openjpa.Log", "SQL=TRACE");
+            jpaPropertyMap.put("openjpa.ConnectionFactoryProperties",
+                    "PrintParameters=true, PrettyPrint=true, PrettyPrintLineLength=120");
+        }
+
+        jpaPropertyMap.put("openjpa.NontransactionalWrite", false);
+
+        jpaPropertyMap.put("openjpa.jdbc.MappingDefaults",
+                "ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict,"
+                + "FieldStrategies='"
+                + "java.util.Locale=org.apache.syncope.core.persistence.jpa.openjpa.LocaleValueHandler,"
+                + "java.lang.Boolean=org.apache.syncope.core.persistence.jpa.openjpa.BooleanValueHandler'");
+
+        jpaPropertyMap.put("openjpa.DataCache", "true");
+        jpaPropertyMap.put("openjpa.QueryCache", "true");
+
+        jpaPropertyMap.put("openjpa.RemoteCommitProvider", env.getProperty("openjpa.RemoteCommitProvider", "sjvm"));
+
+        commonEMFConf.setJpaPropertyMap(jpaPropertyMap);
+        return commonEMFConf;
+    }
+
+    @Bean
+    public EntityFactory entityFactory()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (EntityFactory) Class.forName(env.getProperty("entity.factory")).newInstance();
+    }
+
+    @Bean
+    public PlainSchemaDAO plainSchemaDAO()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (PlainSchemaDAO) Class.forName(env.getProperty("plainSchema.dao")).newInstance();
+    }
+
+    @Bean
+    public PlainAttrDAO plainAttrDAO()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (PlainAttrDAO) Class.forName(env.getProperty("plainAttr.dao")).newInstance();
+    }
+
+    @Bean
+    public PlainAttrValueDAO plainAttrValueDAO()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (PlainAttrValueDAO) Class.forName(env.getProperty("plainAttrValue.dao")).newInstance();
+    }
+
+    @Bean
+    public AnySearchDAO anySearchDAO()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (AnySearchDAO) Class.forName(env.getProperty("any.search.dao")).newInstance();
+    }
+
+    @Bean
+    public UserDAO userDAO()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (UserDAO) Class.forName(env.getProperty("user.dao")).newInstance();
+    }
+
+    @Bean
+    public GroupDAO groupDAO()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (GroupDAO) Class.forName(env.getProperty("group.dao")).newInstance();
+    }
+
+    @Bean
+    public AnyObjectDAO anyObjectDAO()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (AnyObjectDAO) Class.forName(env.getProperty("anyObject.dao")).newInstance();
+    }
+
+    @Bean
+    public ConfDAO confDAO()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (ConfDAO) Class.forName(env.getProperty("conf.dao")).newInstance();
+    }
+
+    @Bean
+    public Validator localValidatorFactoryBean() {
+        return new LocalValidatorFactoryBean();
+    }
+
+    @Bean
+    public ResourceWithFallbackLoader viewsXML() {
+        ResourceWithFallbackLoader viewsXML = new ResourceWithFallbackLoader();
+        viewsXML.setPrimary("file:" + env.getProperty("content.directory") + "/views.xml");
+        viewsXML.setFallback("classpath:views.xml");
+        return viewsXML;
+    }
+
+    @Bean
+    public ResourceWithFallbackLoader indexesXML() {
+        ResourceWithFallbackLoader indexesXML = new ResourceWithFallbackLoader();
+        indexesXML.setPrimary("file:" + env.getProperty("content.directory") + "/indexes.xml");
+        indexesXML.setFallback("classpath:indexes.xml");
+        return indexesXML;
+    }
+}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java
deleted file mode 100644
index 9e44efe..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java
+++ /dev/null
@@ -1,35 +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.core.persistence.jpa.content;
-
-import org.apache.syncope.core.persistence.api.DomainsHolder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public abstract class AbstractContentDealer {
-
-    protected static final Logger LOG = LoggerFactory.getLogger(AbstractContentDealer.class);
-
-    protected static final String ROOT_ELEMENT = "dataset";
-
-    @Autowired
-    protected DomainsHolder domainsHolder;
-
-}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
index 44f1411..885bab3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
@@ -53,6 +53,7 @@ import javax.xml.transform.sax.TransformerHandler;
 import javax.xml.transform.stream.StreamResult;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.content.ContentExporter;
@@ -73,6 +74,8 @@ import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueVa
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.datasource.DataSourceUtils;
 import org.springframework.stereotype.Component;
@@ -83,9 +86,11 @@ import org.xml.sax.helpers.AttributesImpl;
  * Export internal storage content as XML.
  */
 @Component
-public class XMLContentExporter extends AbstractContentDealer implements ContentExporter {
+public class XMLContentExporter implements ContentExporter {
 
-    protected static final Set<String> TABLE_PREFIXES_TO_BE_EXCLUDED = new HashSet<>(Arrays.asList(new String[] {
+    private static final Logger LOG = LoggerFactory.getLogger(XMLContentExporter.class);
+
+    private static final Set<String> TABLE_PREFIXES_TO_BE_EXCLUDED = new HashSet<>(Arrays.asList(new String[] {
         "QRTZ_", "LOGGING", JPAReportExec.TABLE, JPATaskExec.TABLE,
         JPAUser.TABLE, JPAUPlainAttr.TABLE, JPAUPlainAttrValue.TABLE, JPAUPlainAttrUniqueValue.TABLE,
         JPAURelationship.TABLE, JPAUMembership.TABLE,
@@ -93,13 +98,16 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
         JPAARelationship.TABLE, JPAAMembership.TABLE, JPAAccessToken.TABLE
     }));
 
-    protected static final Map<String, String> TABLES_TO_BE_FILTERED =
+    private static final Map<String, String> TABLES_TO_BE_FILTERED =
             Collections.singletonMap("TASK", "DTYPE <> 'PropagationTask'");
 
-    protected static final Map<String, Set<String>> COLUMNS_TO_BE_NULLIFIED =
+    private static final Map<String, Set<String>> COLUMNS_TO_BE_NULLIFIED =
             Collections.singletonMap("SYNCOPEGROUP", Collections.singleton("USEROWNER_ID"));
 
     @Autowired
+    private DomainsHolder domainsHolder;
+
+    @Autowired
     private RealmDAO realmDAO;
 
     private boolean isTableAllowed(final String tableName) {
@@ -376,7 +384,9 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
             throw new IllegalArgumentException("Could not find DataSource for domain " + domain);
         }
 
-        String schema = ApplicationContextProvider.getBeanFactory().getBean(domain + "DatabaseSchema", String.class);
+        String schema = ApplicationContextProvider.getBeanFactory().containsBean(domain + "DatabaseSchema")
+                ? ApplicationContextProvider.getBeanFactory().getBean(domain + "DatabaseSchema", String.class)
+                : null;
 
         Connection conn = null;
         ResultSet rs = null;
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
index 4adfde6..4c17337 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
@@ -27,10 +27,12 @@ import javax.xml.XMLConstants;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
-import org.apache.syncope.core.spring.ApplicationContextProvider;
-import org.apache.syncope.core.spring.ResourceWithFallbackLoader;
 import org.apache.syncope.core.persistence.api.content.ContentLoader;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPAConf;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ResourceWithFallbackLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.core.io.support.PropertiesLoaderUtils;
 import org.springframework.dao.DataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -42,7 +44,9 @@ import org.xml.sax.SAXException;
  * Initialize Database with default content if no data is present already.
  */
 @Component
-public class XMLContentLoader extends AbstractContentDealer implements ContentLoader {
+public class XMLContentLoader implements ContentLoader {
+
+    private static final Logger LOG = LoggerFactory.getLogger(XMLContentLoader.class);
 
     @Resource(name = "viewsXML")
     private ResourceWithFallbackLoader viewsXML;
@@ -51,50 +55,50 @@ public class XMLContentLoader extends AbstractContentDealer implements ContentLo
     private ResourceWithFallbackLoader indexesXML;
 
     @Override
-    public Integer getPriority() {
-        return 0;
+    public int getOrder() {
+        return 400;
     }
 
     @Override
-    public void load() {
-        domainsHolder.getDomains().forEach((domain, datasource) -> {
-            // create EntityManager so OpenJPA will build the SQL schema
-            EntityManagerFactoryUtils.findEntityManagerFactory(
-                    ApplicationContextProvider.getBeanFactory(), domain).createEntityManager();
-
-            JdbcTemplate jdbcTemplate = new JdbcTemplate(datasource);
-            boolean existingData;
+    public void load(final String domain, final DataSource datasource) {
+        LOG.debug("Loading data for domain [{}]", domain);
+
+        // create EntityManager so OpenJPA will build the SQL schema
+        EntityManagerFactoryUtils.findEntityManagerFactory(
+                ApplicationContextProvider.getBeanFactory(), domain).createEntityManager();
+
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(datasource);
+        boolean existingData;
+        try {
+            existingData = jdbcTemplate.queryForObject("SELECT COUNT(0) FROM " + JPAConf.TABLE, Integer.class) > 0;
+        } catch (DataAccessException e) {
+            LOG.error("[{}] Could not access to table " + JPAConf.TABLE, domain, e);
+            existingData = true;
+        }
+
+        if (existingData) {
+            LOG.info("[{}] Data found in the database, leaving untouched", domain);
+        } else {
+            LOG.info("[{}] Empty database found, loading default content", domain);
+
             try {
-                existingData = jdbcTemplate.queryForObject("SELECT COUNT(0) FROM " + JPAConf.TABLE, Integer.class) > 0;
-            } catch (DataAccessException e) {
-                LOG.error("[{}] Could not access to table " + JPAConf.TABLE, domain, e);
-                existingData = true;
+                createViews(domain, datasource);
+            } catch (IOException e) {
+                LOG.error("[{}] While creating views", domain, e);
             }
-
-            if (existingData) {
-                LOG.info("[{}] Data found in the database, leaving untouched", domain);
-            } else {
-                LOG.info("[{}] Empty database found, loading default content", domain);
-
-                try {
-                    createViews(domain, datasource);
-                } catch (IOException e) {
-                    LOG.error("[{}] While creating views", domain, e);
-                }
-                try {
-                    createIndexes(domain, datasource);
-                } catch (IOException e) {
-                    LOG.error("[{}] While creating indexes", domain, e);
-                }
-                try {
-                    ResourceWithFallbackLoader contentXML = ApplicationContextProvider.getBeanFactory().
-                            getBean(domain + "ContentXML", ResourceWithFallbackLoader.class);
-                    loadDefaultContent(domain, contentXML, datasource);
-                } catch (Exception e) {
-                    LOG.error("[{}] While loading default content", domain, e);
-                }
+            try {
+                createIndexes(domain, datasource);
+            } catch (IOException e) {
+                LOG.error("[{}] While creating indexes", domain, e);
             }
-        });
+            try {
+                ResourceWithFallbackLoader contentXML = ApplicationContextProvider.getBeanFactory().
+                        getBean(domain + "ContentXML", ResourceWithFallbackLoader.class);
+                loadDefaultContent(domain, contentXML, datasource);
+            } catch (Exception e) {
+                LOG.error("[{}] While loading default content", domain, e);
+            }
+        }
     }
 
     private void loadDefaultContent(
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
index 1d01d75..d9afe3c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
@@ -27,12 +27,14 @@ import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.jpa.entity.JPADerSchema;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Repository;
 
 @Repository
 public class JPADerSchemaDAO extends AbstractDAO<DerSchema> implements DerSchemaDAO {
 
     @Autowired
+    @Lazy
     private ExternalResourceDAO resourceDAO;
 
     @Override
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java
index 2811367..89507b2 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java
@@ -54,7 +54,7 @@ public class JPAAPlainAttr extends AbstractPlainAttr<AnyObject> implements APlai
     @ManyToOne(fetch = FetchType.EAGER)
     private JPAAMembership membership;
 
-    @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute")
+    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, orphanRemoval = true, mappedBy = "attribute")
     @Valid
     private List<JPAAPlainAttrValue> values = new ArrayList<>();
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java
index f01caa3..40fa835 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java
@@ -58,7 +58,7 @@ public class JPACPlainAttr extends AbstractPlainAttr<Conf> implements CPlainAttr
     /**
      * Values of this attribute (if schema is not UNIQUE).
      */
-    @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute")
+    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, orphanRemoval = true, mappedBy = "attribute")
     @Valid
     private List<JPACPlainAttrValue> values = new ArrayList<>();
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java
index 09a3629..b6d5d86 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java
@@ -47,7 +47,7 @@ public class JPAGPlainAttr extends AbstractPlainAttr<Group> implements GPlainAtt
     @ManyToOne(fetch = FetchType.EAGER)
     private JPAGroup owner;
 
-    @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute")
+    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, orphanRemoval = true, mappedBy = "attribute")
     @Valid
     private List<JPAGPlainAttrValue> values = new ArrayList<>();
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
index b467edc..9069e28 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
@@ -60,7 +60,7 @@ public class JPAUPlainAttr extends AbstractPlainAttr<User> implements UPlainAttr
     /**
      * Values of this attribute (if schema is not UNIQUE).
      */
-    @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute")
+    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, orphanRemoval = true, mappedBy = "attribute")
     @Valid
     private List<JPAUPlainAttrValue> values = new ArrayList<>();
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionAnnotationParser.java
similarity index 51%
copy from core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java
copy to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionAnnotationParser.java
index 0353497..3dfb385 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionAnnotationParser.java
@@ -18,21 +18,21 @@
  */
 package org.apache.syncope.core.persistence.jpa.spring;
 
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.transaction.interceptor.TransactionInterceptor;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.springframework.core.annotation.AnnotationAttributes;
+import org.springframework.transaction.annotation.SpringTransactionAnnotationParser;
+import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
+import org.springframework.transaction.interceptor.TransactionAttribute;
 
-/**
- * Replaces Spring's {@link TransactionInterceptor} with {@link DomainTransactionInterceptor}.
- */
-public class DomainTransactionInterceptorInjector implements BeanFactoryPostProcessor {
+public class DomainTransactionAnnotationParser extends SpringTransactionAnnotationParser {
+
+    private static final long serialVersionUID = -1490842839439224837L;
 
     @Override
-    public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
-        BeanDefinition bd = beanFactory.getBeanDefinition(TransactionInterceptor.class.getName() + "#0");
-        bd.setBeanClassName(DomainTransactionInterceptor.class.getName());
+    protected TransactionAttribute parseTransactionAnnotation(final AnnotationAttributes attributes) {
+        RuleBasedTransactionAttribute rbta =
+                (RuleBasedTransactionAttribute) super.parseTransactionAnnotation(attributes);
+        rbta.setQualifier(AuthContextUtils.getDomain());
+        return rbta;
     }
-
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
index 7d8883a..82b85b7 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
@@ -18,20 +18,20 @@
  */
 package org.apache.syncope.core.persistence.jpa.spring;
 
-import java.lang.reflect.Method;
 import org.aopalliance.intercept.MethodInvocation;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
-import org.springframework.transaction.interceptor.TransactionAttribute;
+import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
 import org.springframework.transaction.interceptor.TransactionAttributeSource;
 import org.springframework.transaction.interceptor.TransactionInterceptor;
 
 /**
  * Extends the standard {@link TransactionInterceptor} by dynamically setting the appropriate
- * {@link TransactionAttribute} qualifier according to the authentication domain of the caller - retrieved via
+ * {@link TransactionAttributeSource} qualifier according to the authentication domain of the caller - retrieved via
  * {@link AuthContextUtils#getDomain()}.
+ *
+ * @see DomainTransactionAnnotationParser
  */
 public class DomainTransactionInterceptor extends TransactionInterceptor {
 
@@ -41,17 +41,7 @@ public class DomainTransactionInterceptor extends TransactionInterceptor {
 
     @Override
     public TransactionAttributeSource getTransactionAttributeSource() {
-        final TransactionAttributeSource origTxAttrSource = super.getTransactionAttributeSource();
-
-        return (final Method method, final Class<?> targetClass) -> {
-            TransactionAttribute txAttr = origTxAttrSource.getTransactionAttribute(method, targetClass);
-
-            if (txAttr instanceof DefaultTransactionAttribute) {
-                ((DefaultTransactionAttribute) txAttr).setQualifier(AuthContextUtils.getDomain());
-            }
-
-            return txAttr;
-        };
+        return new AnnotationTransactionAttributeSource(new DomainTransactionAnnotationParser());
     }
 
     @Override
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java
index 0353497..357bf23 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java
@@ -31,8 +31,11 @@ public class DomainTransactionInterceptorInjector implements BeanFactoryPostProc
 
     @Override
     public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
-        BeanDefinition bd = beanFactory.getBeanDefinition(TransactionInterceptor.class.getName() + "#0");
-        bd.setBeanClassName(DomainTransactionInterceptor.class.getName());
+        for (String name : beanFactory.getBeanNamesForType(TransactionInterceptor.class)) {
+            BeanDefinition bd = beanFactory.getBeanDefinition(name);
+            bd.setBeanClassName(DomainTransactionInterceptor.class.getName());
+            bd.setFactoryBeanName(null);
+            bd.setFactoryMethodName(null);
+        }
     }
-
 }
diff --git a/fit/core-reference/src/main/resources/all/saml2sp-logic.properties b/core/persistence-jpa/src/main/resources/META-INF/spring.factories
similarity index 81%
copy from fit/core-reference/src/main/resources/all/saml2sp-logic.properties
copy to core/persistence-jpa/src/main/resources/META-INF/spring.factories
index fc99f62..fa2d638 100644
--- a/fit/core-reference/src/main/resources/all/saml2sp-logic.properties
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring.factories
@@ -14,11 +14,7 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-conf.directory=${conf.directory}
 
-keystore.name=keystore
-keystore.type=jks
-keystore.storepass=changeit
-keystore.keypass=changeit
-sp.cert.alias=sp
-signature.algorithm=RSA_SHA1
\ No newline at end of file
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  org.apache.syncope.core.persistence.jpa.PersistenceContext,\
+  org.apache.syncope.core.persistence.jpa.MasterDomain
diff --git a/core/persistence-jpa/src/main/resources/domains.xml b/core/persistence-jpa/src/main/resources/domains.xml
deleted file mode 100644
index 75cba84..0000000
--- a/core/persistence-jpa/src/main/resources/domains.xml
+++ /dev/null
@@ -1,61 +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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                           http://www.springframework.org/schema/beans/spring-beans.xsd">
-  
-  <import resource="classpath*:domains/*Domain.xml"/>
-  
-  <bean class="org.apache.syncope.core.persistence.jpa.spring.DomainTransactionInterceptorInjector"/>
-  
-  <bean id="commonEMFConf" class="org.apache.syncope.core.persistence.jpa.spring.CommonEntityManagerFactoryConf">
-    <property name="packagesToScan" value="org.apache.syncope.core.persistence.jpa.entity"/>
-    <property name="validationMode" value="NONE"/>
-    <property name="persistenceUnitPostProcessors">
-      <list>
-        <bean class="org.apache.syncope.core.persistence.jpa.spring.MultiJarAwarePersistenceUnitPostProcessor"/>
-      </list>
-    </property>
-    <property name="jpaPropertyMap">
-      <map>
-        <entry key="openjpa.Log" value="slf4j"/>
-        <!--<entry key="openjpa.Log" value="SQL=TRACE"/>
-        <entry key="openjpa.ConnectionFactoryProperties" 
-        value="PrintParameters=true, PrettyPrint=true, PrettyPrintLineLength=80"/>-->
-                                
-        <entry key="openjpa.NontransactionalWrite" value="false"/>
-
-        <!-- Removed: see https://s.apache.org/openjpaSchemaFactory for more information
-        <entry key="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)"/>-->
-        <entry key="openjpa.jdbc.MappingDefaults" 
-               value="ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict,
-                      FieldStrategies='
-                        java.util.Locale=org.apache.syncope.core.persistence.jpa.openjpa.LocaleValueHandler,
-                        java.lang.Boolean=org.apache.syncope.core.persistence.jpa.openjpa.BooleanValueHandler'"/>
-                
-        <entry key="openjpa.DataCache" value="true"/>
-        <entry key="openjpa.QueryCache" value="true"/>
-        <entry key="openjpa.RemoteCommitProvider" value="${openjpa.RemoteCommitProvider:sjvm}"/>
-      </map>
-    </property>
-  </bean>
-  
-</beans>
diff --git a/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml b/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
deleted file mode 100644
index 722b32c..0000000
--- a/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
+++ /dev/null
@@ -1,110 +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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:tx="http://www.springframework.org/schema/tx"
-       xmlns:util="http://www.springframework.org/schema/util"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                           http://www.springframework.org/schema/beans/spring-beans.xsd                           
-                           http://www.springframework.org/schema/tx
-                           http://www.springframework.org/schema/tx/spring-tx.xsd
-                           http://www.springframework.org/schema/util
-                           http://www.springframework.org/schema/util/spring-util.xsd">
-  
-  <bean id="MasterContentXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${content.directory}/domains/MasterContent.xml"/>
-    <property name="fallback" value="classpath:domains/MasterContent.xml"/>
-  </bean>
-  <bean id="MasterProperties" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${content.directory}/domains/Master.properties"/>
-    <property name="fallback" value="classpath:domains/Master.properties"/>
-  </bean>
-  <bean id="MasterDatabaseSchema" class="java.lang.String">
-    <constructor-arg value="${Master.schema}"/>
-  </bean>
-
-  <!-- Use JNDI datasource as default but, when not available, revert to
-  local datasource, with different properties for execution and testing. 
-  In any case, get all JDBC connections with a determined isolation level. -->
-  <bean id="MasterDataSource" class="org.springframework.jndi.JndiObjectFactoryBean" primary="true">
-    <property name="jndiName" value="java:comp/env/jdbc/syncopeMasterDataSource"/>
-    <property name="defaultObject" ref="localMasterDataSource"/>
-  </bean>
-
-  <bean id="localMasterDataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
-    <property name="driverClassName" value="${Master.driverClassName}"/>
-    <property name="jdbcUrl" value="${Master.url}"/>
-    <property name="username" value="${Master.username}"/>
-    <property name="password" value="${Master.password}"/>
-    <!-- connection pool configuration - transaction isolation, default READ_COMMITTED (see SYNCOPE-202) -->
-    <property name="transactionIsolation">
-      <util:constant static-field="${Master.pool.transactionIsolation:java.sql.Connection.TRANSACTION_READ_COMMITTED}"/>
-    </property>
-    <!-- connection pool configuration - default values taken from HikariConfig default values -->
-    <property name="maximumPoolSize" value="${Master.pool.maxActive:8}"/>
-    <property name="minimumIdle" value="${Master.pool.minIdle:0}"/>
-  </bean>
-  
-  <bean class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
-    <property name="dataSource" ref="MasterDataSource"/>
-    <property name="enabled" value="true"/>
-    <property name="databasePopulator">
-      <bean class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
-        <property name="continueOnError" value="true"/>
-        <property name="ignoreFailedDrops" value="true"/>
-        <property name="sqlScriptEncoding" value="UTF-8"/>
-        <property name="scripts">
-          <array>
-            <value type="org.springframework.core.io.Resource">
-              classpath:/audit/${Master.audit.sql}
-            </value>
-          </array>
-        </property>
-      </bean>
-    </property>
-  </bean>
-  
-  <bean id="MasterEntityManagerFactory"
-        class="org.apache.syncope.core.persistence.jpa.spring.DomainEntityManagerFactoryBean">
-    <property name="mappingResources">
-      <list>
-        <value>${Master.orm}</value>
-      </list>
-    </property>
-    <property name="persistenceUnitName" value="Master"/>
-    <property name="dataSource" ref="MasterDataSource"/>
-    <property name="jpaVendorAdapter">
-      <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
-        <property name="showSql" value="false"/>
-        <property name="generateDdl" value="true"/>
-        <property name="databasePlatform" value="${Master.databasePlatform}"/>
-      </bean>
-    </property>
-    <property name="commonEntityManagerFactoryConf" ref="commonEMFConf"/>
-  </bean>  
-
-  <bean id="MasterTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
-    <property name="entityManagerFactory" ref="MasterEntityManagerFactory"/>
-    <qualifier value="Master"/>
-  </bean>
-  
-  <tx:annotation-driven transaction-manager="MasterTransactionManager"/>
-  
-</beans>
\ No newline at end of file
diff --git a/core/persistence-jpa/src/main/resources/persistenceContext.xml b/core/persistence-jpa/src/main/resources/persistenceContext.xml
deleted file mode 100644
index 577ab78..0000000
--- a/core/persistence-jpa/src/main/resources/persistenceContext.xml
+++ /dev/null
@@ -1,54 +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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                           http://www.springframework.org/schema/beans/spring-beans.xsd
-                           http://www.springframework.org/schema/context
-                           http://www.springframework.org/schema/context/spring-context.xsd">
-  
-  <import resource="domains.xml"/>
-
-  <context:annotation-config/>
-  
-  <context:component-scan base-package="org.apache.syncope.core.persistence.jpa"/>
-  <bean class="${entity.factory}"/>
-  <bean class="${plainSchema.dao}"/>
-  <bean class="${plainAttr.dao}"/>
-  <bean class="${plainAttrValue.dao}"/>
-  <bean class="${any.search.dao}"/>
-  <bean class="${user.dao}"/>
-  <bean class="${group.dao}"/>
-  <bean class="${anyObject.dao}"/>
-  <bean class="${conf.dao}"/>
-
-  <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
-
-  <bean id="viewsXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${content.directory}/views.xml"/>
-    <property name="fallback" value="classpath:views.xml"/>
-  </bean>
-  <bean id="indexesXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${content.directory}/indexes.xml"/>
-    <property name="fallback" value="classpath:indexes.xml"/>
-  </bean>
-  
-</beans>
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
index a957b27..a112e7f 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
@@ -31,7 +31,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.orm.jpa.EntityManagerFactoryUtils;
 import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
 
-@SpringJUnitConfig(locations = { "classpath:persistenceTest.xml" })
+@SpringJUnitConfig(classes = { PersistenceTestContext.class })
 public abstract class AbstractTest {
 
     @Autowired
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyImplementationLookup.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyImplementationLookup.java
index 376534c..c80c33c 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyImplementationLookup.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyImplementationLookup.java
@@ -42,16 +42,11 @@ import org.springframework.stereotype.Component;
 public class DummyImplementationLookup implements ImplementationLookup {
 
     @Override
-    public Integer getPriority() {
+    public int getOrder() {
         return -1;
     }
 
     @Override
-    public void load() {
-        // do nothing
-    }
-
-    @Override
     public Set<String> getClassNames(final ImplementationType type) {
         return Collections.emptySet();
     }
@@ -100,5 +95,4 @@ public class DummyImplementationLookup implements ImplementationLookup {
     public Set<Class<?>> getAuditAppenderClasses() {
         return Collections.emptySet();
     }
-
 }
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/PersistenceTestContext.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/PersistenceTestContext.java
new file mode 100644
index 0000000..a25f912
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/PersistenceTestContext.java
@@ -0,0 +1,70 @@
+/*
+ * 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.core.persistence.jpa;
+
+import java.io.IOException;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.DefaultPasswordGenerator;
+import org.apache.syncope.core.spring.security.PasswordGenerator;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
+
+@PropertySource("classpath:security.properties")
+@Import(PersistenceContext.class)
+@Configuration
+public class PersistenceTestContext {
+
+    @Value("${adminUser}")
+    private String adminUser;
+
+    @Value("${anonymousUser}")
+    private String anonymousUser;
+
+    @Bean
+    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() throws IOException {
+        PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
+        pspc.setIgnoreResourceNotFound(true);
+        pspc.setIgnoreUnresolvablePlaceholders(true);
+        return pspc;
+    }
+
+    @Bean
+    public String adminUser() {
+        return adminUser;
+    }
+
+    @Bean
+    public String anonymousUser() {
+        return anonymousUser;
+    }
+
+    @Bean
+    public ApplicationContextProvider applicationContextProvider() {
+        return new ApplicationContextProvider();
+    }
+
+    @Bean
+    public PasswordGenerator passwordGenerator() {
+        return new DefaultPasswordGenerator();
+    }
+}
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/TestInitializer.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/TestInitializer.java
index ec32cf2..49ab215 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/TestInitializer.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/TestInitializer.java
@@ -18,20 +18,53 @@
  */
 package org.apache.syncope.core.persistence.jpa;
 
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.content.ContentLoader;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.stereotype.Component;
 
 @Component
-public class TestInitializer implements InitializingBean {
+public class TestInitializer implements InitializingBean, ApplicationContextAware {
+
+    private ConfigurableApplicationContext ctx;
+
+    @Autowired
+    private DomainLoader domainLoader;
+
+    @Autowired
+    private DomainsHolder domainsHolder;
 
     @Autowired
     private ContentLoader contentLoader;
 
     @Override
-    public void afterPropertiesSet() throws Exception {
-        contentLoader.load();
+    public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
+        this.ctx = (ConfigurableApplicationContext) ctx;
     }
 
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        ApplicationContextProvider.setApplicationContext(ctx);
+        ApplicationContextProvider.setBeanFactory((DefaultListableBeanFactory) ctx.getBeanFactory());
+
+        domainLoader.load();
+
+        contentLoader.load(
+                SyncopeConstants.MASTER_DOMAIN,
+                domainsHolder.getDomains().get(SyncopeConstants.MASTER_DOMAIN));
+        if (domainsHolder.getDomains().containsKey("Two")) {
+            contentLoader.load(
+                    "Two",
+                    domainsHolder.getDomains().get("Two"));
+        }
+
+    }
 }
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
index e84f882..fe30eee 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
@@ -177,7 +177,7 @@ public class PlainSchemaTest extends AbstractTest {
 
     @Test
     public void deleteSurname() {
-        // search for user schema fullname
+        // search for user schema surname
         PlainSchema schema = plainSchemaDAO.find("surname");
         assertNotNull(schema);
 
@@ -202,7 +202,7 @@ public class PlainSchemaTest extends AbstractTest {
         assertEquals(5, labels.size());
         assertEquals(2, schema.getLabels().size());
 
-        // delete user schema fullname
+        // delete user schema surname
         plainSchemaDAO.delete("surname");
 
         entityManager().flush();
@@ -218,15 +218,13 @@ public class PlainSchemaTest extends AbstractTest {
 
     @Test
     public void deleteFirstname() {
-        assertEquals(6, resourceDAO.find("resource-db-pull").
-                getProvision(anyTypeDAO.findUser()).get().getMapping().getItems().size());
+        int pre = resourceDAO.find("resource-db-pull").
+                getProvision(anyTypeDAO.findUser()).get().getMapping().getItems().size();
 
         plainSchemaDAO.delete("firstname");
         assertNull(plainSchemaDAO.find("firstname"));
 
-        entityManager().flush();
-
-        assertEquals(5, resourceDAO.find("resource-db-pull").
+        assertEquals(pre - 1, resourceDAO.find("resource-db-pull").
                 getProvision(anyTypeDAO.findUser()).get().getMapping().getItems().size());
     }
 }
diff --git a/core/persistence-jpa/src/test/resources/domains/Two.properties b/core/persistence-jpa/src/test/resources/domains/Two.properties
index ea19bd7..e11614d 100644
--- a/core/persistence-jpa/src/test/resources/domains/Two.properties
+++ b/core/persistence-jpa/src/test/resources/domains/Two.properties
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 Two.driverClassName=org.h2.Driver
-Two.url=jdbc:h2:file:${conf.directory}/syncopetwo.db
+Two.url=jdbc:h2:mem:syncopetwo;DB_CLOSE_DELAY=-1
 Two.schema=
 Two.username=sa
 Two.password=
diff --git a/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml b/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
deleted file mode 100644
index d0b741f..0000000
--- a/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
+++ /dev/null
@@ -1,110 +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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:tx="http://www.springframework.org/schema/tx"
-       xmlns:util="http://www.springframework.org/schema/util"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                           http://www.springframework.org/schema/beans/spring-beans.xsd                           
-                           http://www.springframework.org/schema/tx
-                           http://www.springframework.org/schema/tx/spring-tx.xsd
-                           http://www.springframework.org/schema/util
-                           http://www.springframework.org/schema/util/spring-util.xsd">
-  
-  <bean id="TwoContentXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${content.directory}/domains/TwoContent.xml"/>
-    <property name="fallback" value="classpath:domains/TwoContent.xml"/>
-  </bean>
-  <bean id="TwoProperties" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${content.directory}/domains/Two.properties"/>
-    <property name="fallback" value="classpath:domains/Two.properties"/>
-  </bean>
-  <bean id="TwoDatabaseSchema" class="java.lang.String">
-    <constructor-arg value="${Two.schema}"/>
-  </bean>
-
-  <!-- Use JNDI datasource as default but, when not available, revert to
-  local datasource, with different properties for execution and testing. 
-  In any case, get all JDBC connections with a determined isolation level. -->
-  <bean id="TwoDataSource" class="org.springframework.jndi.JndiObjectFactoryBean" primary="true">
-    <property name="jndiName" value="java:comp/env/jdbc/syncopeTwoDataSource"/>
-    <property name="defaultObject" ref="localTwoDataSource"/>
-  </bean>
-
-  <bean id="localTwoDataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
-    <property name="driverClassName" value="${Two.driverClassName}"/>
-    <property name="jdbcUrl" value="${Two.url}"/>
-    <property name="username" value="${Two.username}"/>
-    <property name="password" value="${Two.password}"/>
-    <!-- connection pool configuration - transaction isolation, default READ_COMMITTED (see SYNCOPE-202) -->
-    <property name="transactionIsolation">
-      <util:constant static-field="${Two.pool.transactionIsolation:java.sql.Connection.TRANSACTION_READ_COMMITTED}"/>
-    </property>
-    <!-- connection pool configuration - default values taken from HikariConfig default values -->
-    <property name="maximumPoolSize" value="${Two.pool.maxActive:8}"/>
-    <property name="minimumIdle" value="${Two.pool.minIdle:0}"/>
-  </bean>
-  
-  <bean class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
-    <property name="dataSource" ref="TwoDataSource"/>
-    <property name="enabled" value="true"/>
-    <property name="databasePopulator">
-      <bean class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
-        <property name="continueOnError" value="true"/>
-        <property name="ignoreFailedDrops" value="true"/>
-        <property name="sqlScriptEncoding" value="UTF-8"/>
-        <property name="scripts">
-          <array>
-            <value type="org.springframework.core.io.Resource">
-              classpath:/audit/${Two.audit.sql}
-            </value>
-          </array>
-        </property>
-      </bean>
-    </property>
-  </bean>
-  
-  <bean id="TwoEntityManagerFactory"
-        class="org.apache.syncope.core.persistence.jpa.spring.DomainEntityManagerFactoryBean">
-    <property name="mappingResources">
-      <list>
-        <value>${Two.orm}</value>
-      </list>
-    </property>
-    <property name="persistenceUnitName" value="Two"/>
-    <property name="dataSource" ref="TwoDataSource"/>
-    <property name="jpaVendorAdapter">
-      <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
-        <property name="showSql" value="false"/>
-        <property name="generateDdl" value="true"/>
-        <property name="databasePlatform" value="${Two.databasePlatform}"/>
-      </bean>
-    </property>
-    <property name="commonEntityManagerFactoryConf" ref="commonEMFConf"/>
-  </bean>  
-
-  <bean id="TwoTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
-    <property name="entityManagerFactory" ref="TwoEntityManagerFactory"/>
-    <qualifier value="Two"/>
-  </bean>
-  
-  <tx:annotation-driven transaction-manager="TwoTransactionManager"/>
-
-</beans>
diff --git a/core/persistence-jpa/src/test/resources/persistenceTest.xml b/core/persistence-jpa/src/test/resources/persistenceTest.xml
deleted file mode 100644
index 80f854b..0000000
--- a/core/persistence-jpa/src/test/resources/persistenceTest.xml
+++ /dev/null
@@ -1,55 +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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                           http://www.springframework.org/schema/beans/spring-beans.xsd
-                           http://www.springframework.org/schema/context
-                           http://www.springframework.org/schema/context/spring-context.xsd">
-
-  <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
-    <property name="locations">
-      <list>
-        <value>classpath:persistence.properties</value>
-        <value>classpath:domains/*.properties</value>
-        <value>classpath:security.properties</value>
-      </list>
-    </property>
-    <property name="ignoreResourceNotFound" value="true"/>
-    <property name="ignoreUnresolvablePlaceholders" value="true"/>
-  </bean>
-  
-  <bean class="org.apache.syncope.core.spring.ApplicationContextProvider"/>
-
-  <bean id="adminUser" class="java.lang.String">
-    <constructor-arg value="${adminUser}"/>
-  </bean>
-  <bean id="anonymousUser" class="java.lang.String">
-    <constructor-arg value="${anonymousUser}"/>
-  </bean>
-  
-  <context:component-scan base-package="org.apache.syncope.core.spring.security"/>
-
-  <bean class="org.apache.syncope.core.spring.security.DefaultPasswordGenerator"/>
-
-  <import resource="persistenceContext.xml"/>
-
-</beans>
diff --git a/core/pom.xml b/core/pom.xml
index 9c0687b..aed7643 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -87,6 +87,7 @@ under the License.
     <module>provisioning-java</module>
     <module>workflow-api</module>
     <module>workflow-java</module>
+    <module>starter</module>
     <module>upgrade</module>
   </modules>
 </project>
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorLoader.java
similarity index 62%
copy from core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java
copy to core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorLoader.java
index 98392af..5db2ff7 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorLoader.java
@@ -18,20 +18,29 @@
  */
 package org.apache.syncope.core.provisioning.java;
 
-import org.apache.syncope.core.persistence.api.content.ContentLoader;
-import org.springframework.beans.factory.InitializingBean;
+import javax.sql.DataSource;
+import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
+import org.apache.syncope.core.provisioning.api.ConnectorFactory;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
-public class TestInitializer implements InitializingBean {
+public class ConnectorLoader implements SyncopeCoreLoader {
 
     @Autowired
-    private ContentLoader contentLoader;
+    private ConnectorFactory connectorFactory;
 
     @Override
-    public void afterPropertiesSet() throws Exception {
-        contentLoader.load();
+    public int getOrder() {
+        return 100;
     }
 
+    @Override
+    public void load(final String domain, final DataSource datasource) {
+        AuthContextUtils.execWithAuthContext(domain, () -> {
+            connectorFactory.load();
+            return null;
+        });
+    }
 }
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
index 0d4bcde..ba2f277 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
@@ -27,7 +27,6 @@ import java.util.Set;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
-import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
@@ -49,7 +48,7 @@ import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
 @Component
-public class ConnectorManager implements ConnectorRegistry, ConnectorFactory, SyncopeLoader {
+public class ConnectorManager implements ConnectorRegistry, ConnectorFactory {
 
     private static final Logger LOG = LoggerFactory.getLogger(ConnectorManager.class);
 
@@ -67,11 +66,6 @@ public class ConnectorManager implements ConnectorRegistry, ConnectorFactory, Sy
 
     private EntityFactory entityFactory;
 
-    @Override
-    public Integer getPriority() {
-        return 100;
-    }
-
     private String getBeanName(final ExternalResource resource) {
         return String.format("connInstance-%s-%S-%s",
                 AuthContextUtils.getDomain(), resource.getConnector().getKey(), resource.getKey());
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java
new file mode 100644
index 0000000..c4de243
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java
@@ -0,0 +1,109 @@
+/*
+ * 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.core.provisioning.java;
+
+import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
+import org.apache.syncope.core.provisioning.api.AuditManager;
+import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
+import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.ImportResource;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+
+@PropertySource("classpath:connid.properties")
+@PropertySource("classpath:mail.properties")
+@PropertySource("classpath:provisioning.properties")
+@PropertySource(value = "file:${conf.directory}/connid.properties", ignoreResourceNotFound = true)
+@PropertySource(value = "file:${conf.directory}/mail.properties", ignoreResourceNotFound = true)
+@PropertySource(value = "file:${conf.directory}/provisioning.properties", ignoreResourceNotFound = true)
+@ImportResource("classpath:/provisioningContext.xml")
+@ComponentScan("org.apache.syncope.core.provisioning.java")
+@Configuration
+public class ProvisioningContext implements EnvironmentAware {
+
+    private Environment env;
+
+    @Override
+    public void setEnvironment(final Environment env) {
+        this.env = env;
+    }
+
+    @Bean
+    public PropagationTaskExecutor propagationTaskExecutor()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (PropagationTaskExecutor) Class.forName(env.getProperty("propagationTaskExecutor")).
+                newInstance();
+    }
+
+    @Bean
+    public UserProvisioningManager userProvisioningManager()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (UserProvisioningManager) Class.forName(env.getProperty("userProvisioningManager")).
+                newInstance();
+    }
+
+    @Bean
+    public GroupProvisioningManager groupProvisioningManager()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (GroupProvisioningManager) Class.forName(env.getProperty("groupProvisioningManager")).
+                newInstance();
+    }
+
+    @Bean
+    public AnyObjectProvisioningManager anyObjectProvisioningManager()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (AnyObjectProvisioningManager) Class.forName(env.getProperty("anyObjectProvisioningManager")).
+                newInstance();
+    }
+
+    @Bean
+    public VirAttrCache virAttrCache()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (VirAttrCache) Class.forName(env.getProperty("virAttrCache")).
+                newInstance();
+    }
+
+    @Bean
+    public NotificationManager notificationManager()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (NotificationManager) Class.forName(env.getProperty("notificationManager")).
+                newInstance();
+    }
+
+    @Bean
+    public AuditManager auditManager()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (AuditManager) Class.forName(env.getProperty("auditManager")).
+                newInstance();
+    }
+}
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
index c59c881..2a38f1e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
@@ -22,6 +22,7 @@ import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -47,8 +48,8 @@ import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
-import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.persistence.api.DomainsHolder;
+import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
 import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.quartz.CronScheduleBuilder;
@@ -78,7 +79,7 @@ import org.apache.syncope.core.provisioning.java.job.report.ReportJob;
 import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
 import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
 
-public class JobManagerImpl implements JobManager, SyncopeLoader {
+public class JobManagerImpl implements JobManager, SyncopeCoreLoader {
 
     private static final Logger LOG = LoggerFactory.getLogger(JobManager.class);
 
@@ -290,13 +291,13 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
     }
 
     @Override
-    public Integer getPriority() {
-        return 200;
+    public int getOrder() {
+        return 500;
     }
 
     @Transactional
     @Override
-    public void load() {
+    public void load(final String domain, final DataSource datasource) {
         if (disableQuartzInstance) {
             String instanceId = "AUTO";
             try {
@@ -311,7 +312,7 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
             return;
         }
 
-        final Pair<String, Long> conf = AuthContextUtils.execWithAuthContext(SyncopeConstants.MASTER_DOMAIN, () -> {
+        Pair<String, Long> conf = AuthContextUtils.execWithAuthContext(SyncopeConstants.MASTER_DOMAIN, () -> {
             String notificationJobCronExpression = StringUtils.EMPTY;
 
             Optional<? extends CPlainAttr> notificationJobCronExp = confDAO.find("notificationjob.cronExpression");
@@ -326,83 +327,80 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
             return Pair.of(notificationJobCronExpression, interruptMaxRetries);
         });
 
-        for (String domain : domainsHolder.getDomains().keySet()) {
-            AuthContextUtils.execWithAuthContext(domain, () -> {
-                // 1. jobs for SchedTasks
-                Set<SchedTask> tasks = new HashSet<>(taskDAO.<SchedTask>findAll(TaskType.SCHEDULED));
-                tasks.addAll(taskDAO.<PullTask>findAll(TaskType.PULL));
-                tasks.addAll(taskDAO.<PushTask>findAll(TaskType.PUSH));
+        AuthContextUtils.execWithAuthContext(domain, () -> {
+            // 1. jobs for SchedTasks
+            Set<SchedTask> tasks = new HashSet<>(taskDAO.<SchedTask>findAll(TaskType.SCHEDULED));
+            tasks.addAll(taskDAO.<PullTask>findAll(TaskType.PULL));
+            tasks.addAll(taskDAO.<PushTask>findAll(TaskType.PUSH));
 
-                boolean loadException = false;
-                for (Iterator<SchedTask> it = tasks.iterator(); it.hasNext() && !loadException;) {
-                    SchedTask task = it.next();
+            boolean loadException = false;
+            for (Iterator<SchedTask> it = tasks.iterator(); it.hasNext() && !loadException;) {
+                SchedTask task = it.next();
+                try {
+                    register(task, task.getStartAt(), conf.getRight());
+                } catch (Exception e) {
+                    LOG.error("While loading job instance for task " + task.getKey(), e);
+                    loadException = true;
+                }
+            }
+
+            if (loadException) {
+                LOG.debug("Errors while loading job instances for tasks, aborting");
+            } else {
+                // 2. jobs for Reports
+                for (Iterator<Report> it = reportDAO.findAll().iterator(); it.hasNext() && !loadException;) {
+                    Report report = it.next();
                     try {
-                        register(task, task.getStartAt(), conf.getRight());
+                        register(report, null, conf.getRight());
                     } catch (Exception e) {
-                        LOG.error("While loading job instance for task " + task.getKey(), e);
+                        LOG.error("While loading job instance for report " + report.getName(), e);
                         loadException = true;
                     }
                 }
 
                 if (loadException) {
-                    LOG.debug("Errors while loading job instances for tasks, aborting");
-                } else {
-                    // 2. jobs for Reports
-                    for (Iterator<Report> it = reportDAO.findAll().iterator(); it.hasNext() && !loadException;) {
-                        Report report = it.next();
-                        try {
-                            register(report, null, conf.getRight());
-                        } catch (Exception e) {
-                            LOG.error("While loading job instance for report " + report.getName(), e);
-                            loadException = true;
-                        }
-                    }
-
-                    if (loadException) {
-                        LOG.debug("Errors while loading job instances for reports, aborting");
-                    }
+                    LOG.debug("Errors while loading job instances for reports, aborting");
                 }
+            }
 
-                return null;
-            });
-        }
+            return null;
+        });
 
-        Map<String, Object> jobMap = new HashMap<>();
-        jobMap.put(JobManager.DOMAIN_KEY, AuthContextUtils.getDomain());
+        if (SyncopeConstants.MASTER_DOMAIN.equals(domain)) {
+            // 3. NotificationJob
+            if (StringUtils.isBlank(conf.getLeft())) {
+                LOG.debug("Empty value provided for {}'s cron, not registering anything on Quartz",
+                        NotificationJob.class.getSimpleName());
+            } else {
+                LOG.debug("{}'s cron expression: {} - registering Quartz job and trigger",
+                        NotificationJob.class.getSimpleName(), conf.getLeft());
 
-        // 3. NotificationJob
-        if (StringUtils.isBlank(conf.getLeft())) {
-            LOG.debug("Empty value provided for {}'s cron, not registering anything on Quartz",
-                    NotificationJob.class.getSimpleName());
-        } else {
-            LOG.debug("{}'s cron expression: {} - registering Quartz job and trigger",
-                    NotificationJob.class.getSimpleName(), conf.getLeft());
+                try {
+                    NotificationJob job = createSpringBean(NotificationJob.class);
+                    registerJob(
+                            NOTIFICATION_JOB.getName(),
+                            job,
+                            conf.getLeft(),
+                            null,
+                            Collections.emptyMap());
+                } catch (Exception e) {
+                    LOG.error("While loading {} instance", NotificationJob.class.getSimpleName(), e);
+                }
+            }
 
+            // 4. SystemLoadReporterJob (fixed schedule, every minute)
+            LOG.debug("Registering {}", SystemLoadReporterJob.class);
             try {
-                NotificationJob job = createSpringBean(NotificationJob.class);
+                SystemLoadReporterJob job = createSpringBean(SystemLoadReporterJob.class);
                 registerJob(
-                        NOTIFICATION_JOB.getName(),
+                        StringUtils.uncapitalize(SystemLoadReporterJob.class.getSimpleName()),
                         job,
-                        conf.getLeft(),
+                        "0 * * * * ?",
                         null,
-                        jobMap);
+                        Collections.emptyMap());
             } catch (Exception e) {
-                LOG.error("While loading {} instance", NotificationJob.class.getSimpleName(), e);
+                LOG.error("While loading {} instance", SystemLoadReporterJob.class.getSimpleName(), e);
             }
         }
-
-        // 4. SystemLoadReporterJob (fixed schedule, every minute)
-        LOG.debug("Registering {}", SystemLoadReporterJob.class);
-        try {
-            SystemLoadReporterJob job = createSpringBean(SystemLoadReporterJob.class);
-            registerJob(
-                    StringUtils.uncapitalize(SystemLoadReporterJob.class.getSimpleName()),
-                    job,
-                    "0 * * * * ?",
-                    null,
-                    jobMap);
-        } catch (Exception e) {
-            LOG.error("While loading {} instance", SystemLoadReporterJob.class.getSimpleName(), e);
-        }
     }
 }
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/DefaultNotificationJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/DefaultNotificationJobDelegate.java
index f33bf1d..23b34de 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/DefaultNotificationJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/DefaultNotificationJobDelegate.java
@@ -87,7 +87,7 @@ public class DefaultNotificationJobDelegate implements InitializingBean, Notific
 
             Properties javaMailProperties = javaMailSender.getJavaMailProperties();
 
-            Properties props = PropertyUtils.read(Encryptor.class, "mail.properties", "conf.directory").getLeft();
+            Properties props = PropertyUtils.read(Encryptor.class, "mail.properties", "conf.directory");
             for (Enumeration<?> e = props.propertyNames(); e.hasMoreElements();) {
                 String prop = (String) e.nextElement();
                 if (prop.startsWith("mail.smtp.")) {
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
index 5931816..d8ce641 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
@@ -66,7 +66,6 @@ import org.quartz.JobExecutionException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
-@Transactional(rollbackFor = Throwable.class)
 public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHandler<PullTask, PullActions>
         implements SyncopePullResultHandler {
 
@@ -113,15 +112,15 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
         this.executor = executor;
     }
 
+    @Transactional
     @Override
     public boolean handle(final SyncDelta delta) {
         Provision provision = null;
         try {
-            provision = profile.getTask().getResource().getProvision(delta.getObject().getObjectClass()).orElse(null);
-            if (provision == null) {
-                throw new JobExecutionException("No provision found on " + profile.getTask().getResource() + " for "
-                        + delta.getObject().getObjectClass());
-            }
+            provision = profile.getTask().getResource().getProvision(delta.getObject().getObjectClass()).
+                    orElseThrow(() -> new JobExecutionException(
+                    "No provision found on " + profile.getTask().getResource() + " for "
+                    + delta.getObject().getObjectClass()));
 
             doHandle(delta, provision);
             executor.reportHandled(delta.getObjectClass(), delta.getObject().getName());
@@ -649,7 +648,7 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
 
         List<ProvisioningReport> results = new ArrayList<>();
 
-        for (String key : anyKeys) {
+        anyKeys.forEach(key -> {
             Object output;
             Result resultStatus = Result.FAILURE;
 
@@ -711,7 +710,7 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
             } catch (Exception e) {
                 LOG.error("Could not delete {} {}", provision.getAnyType().getKey(), key, e);
             }
-        }
+        });
 
         return results;
     }
diff --git a/fit/core-reference/src/main/resources/logic.properties b/core/provisioning-java/src/main/resources/META-INF/spring.factories
similarity index 82%
copy from fit/core-reference/src/main/resources/logic.properties
copy to core/provisioning-java/src/main/resources/META-INF/spring.factories
index 802e7853..0c9c1e3 100644
--- a/fit/core-reference/src/main/resources/logic.properties
+++ b/core/provisioning-java/src/main/resources/META-INF/spring.factories
@@ -14,5 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-logicInvocationHandler=org.apache.syncope.core.logic.LogicInvocationHandler
-classPathScanImplementationLookup=org.apache.syncope.fit.core.reference.ITImplementationLookup
+
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  org.apache.syncope.core.provisioning.java.ProvisioningContext
diff --git a/core/provisioning-java/src/main/resources/provisioningContext.xml b/core/provisioning-java/src/main/resources/provisioningContext.xml
index 8dbd43a..51ee36b 100644
--- a/core/provisioning-java/src/main/resources/provisioningContext.xml
+++ b/core/provisioning-java/src/main/resources/provisioningContext.xml
@@ -19,17 +19,12 @@ under the License.
 -->
 <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:context="http://www.springframework.org/schema/context"
        xmlns:task="http://www.springframework.org/schema/task"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
-                           http://www.springframework.org/schema/context
-                           http://www.springframework.org/schema/context/spring-context.xsd
                            http://www.springframework.org/schema/task
                            http://www.springframework.org/schema/task/spring-task.xsd">
   
-  <context:component-scan base-package="org.apache.syncope.core.provisioning.java"/>
-
   <!-- Used by AsyncConnectorFacade -->
   <task:annotation-driven executor="asyncConnectorFacadeExecutor"/>
   <task:executor id="asyncConnectorFacadeExecutor"
@@ -40,13 +35,6 @@ under the License.
                  pool-size="${propagationTaskExecutorAsyncExecutor.poolSize}"
                  queue-capacity="${propagationTaskExecutorAsyncExecutor.queueCapacity}"
                  rejection-policy="ABORT"/>
-  <bean class="${propagationTaskExecutor}"/>
-  
-  <bean class="${userProvisioningManager}"/>
-  <bean class="${groupProvisioningManager}"/>
-  <bean class="${anyObjectProvisioningManager}"/>
-  <bean class="${notificationManager}"/>
-  <bean class="${auditManager}"/>
 
   <bean id="quartzDataSourceInit" class="org.apache.syncope.core.provisioning.java.job.SchedulerDBInit">
     <property name="dataSource" ref="MasterDataSource"/>
@@ -109,11 +97,6 @@ under the License.
 
   <bean class="org.apache.syncope.core.provisioning.java.propagation.PropagationManagerImpl"/>
 
-  <bean id="virAttrCache" class="${virAttrCache}" scope="singleton">
-    <property name="ttl" value="60"/>
-    <property name="maxCacheSize" value="5000"/>
-  </bean>
-
   <bean id="connIdBundleManager" class="org.apache.syncope.core.provisioning.java.ConnIdBundleManagerImpl">
     <property name="stringLocations" value="${connid.locations}"/>
   </bean>
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
index ad660e7..b120f93 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
@@ -24,12 +24,7 @@ import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.springframework.orm.jpa.EntityManagerFactoryUtils;
 import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
 
-@SpringJUnitConfig(locations = {
-    "classpath:persistenceTest.xml",
-    "classpath:provisioningContext.xml",
-    "classpath:workflowContext.xml",
-    "classpath:provisioningTest.xml"
-})
+@SpringJUnitConfig(classes = { ProvisioningTestContext.class })
 public abstract class AbstractTest {
 
     protected EntityManager entityManager() {
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/DummyImplementationLookup.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/DummyImplementationLookup.java
index 2bdf518..91fce4d 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/DummyImplementationLookup.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/DummyImplementationLookup.java
@@ -42,16 +42,11 @@ import org.springframework.stereotype.Component;
 public class DummyImplementationLookup implements ImplementationLookup {
 
     @Override
-    public Integer getPriority() {
+    public int getOrder() {
         return -1;
     }
 
     @Override
-    public void load() {
-        // do nothing
-    }
-
-    @Override
     public Set<String> getClassNames(final ImplementationType type) {
         return Collections.emptySet();
     }
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ProvisioningTestContext.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ProvisioningTestContext.java
new file mode 100644
index 0000000..0b5123c
--- /dev/null
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ProvisioningTestContext.java
@@ -0,0 +1,41 @@
+/*
+ * 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.core.provisioning.java;
+
+import java.io.IOException;
+import org.apache.syncope.core.persistence.jpa.PersistenceContext;
+import org.apache.syncope.core.spring.security.SecurityContext;
+import org.apache.syncope.core.workflow.java.WorkflowContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
+
+@Import({ SecurityContext.class, PersistenceContext.class, ProvisioningContext.class, WorkflowContext.class })
+@Configuration
+public class ProvisioningTestContext {
+
+    @Bean
+    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() throws IOException {
+        PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
+        pspc.setIgnoreResourceNotFound(true);
+        pspc.setIgnoreUnresolvablePlaceholders(true);
+        return pspc;
+    }
+}
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java
index 98392af..99cba07 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java
@@ -18,20 +18,53 @@
  */
 package org.apache.syncope.core.provisioning.java;
 
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.content.ContentLoader;
+import org.apache.syncope.core.persistence.jpa.DomainLoader;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.stereotype.Component;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
 
 @Component
-public class TestInitializer implements InitializingBean {
+public class TestInitializer implements InitializingBean, ApplicationContextAware {
+
+    private ConfigurableApplicationContext ctx;
+
+    @Autowired
+    private DomainLoader domainLoader;
+
+    @Autowired
+    private DomainsHolder domainsHolder;
 
     @Autowired
     private ContentLoader contentLoader;
 
     @Override
-    public void afterPropertiesSet() throws Exception {
-        contentLoader.load();
+    public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
+        this.ctx = (ConfigurableApplicationContext) ctx;
     }
 
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        ApplicationContextProvider.setApplicationContext(ctx);
+        ApplicationContextProvider.setBeanFactory((DefaultListableBeanFactory) ctx.getBeanFactory());
+
+        if (!TransactionSynchronizationManager.isSynchronizationActive()) {
+            TransactionSynchronizationManager.initSynchronization();
+        }
+
+        domainLoader.load();
+
+        contentLoader.load(
+                SyncopeConstants.MASTER_DOMAIN,
+                domainsHolder.getDomains().get(SyncopeConstants.MASTER_DOMAIN));
+    }
 }
diff --git a/core/provisioning-java/src/test/resources/provisioningTest.xml b/core/provisioning-java/src/test/resources/provisioningTest.xml
deleted file mode 100644
index 903d2c7..0000000
--- a/core/provisioning-java/src/test/resources/provisioningTest.xml
+++ /dev/null
@@ -1,63 +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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                           http://www.springframework.org/schema/beans/spring-beans.xsd">
-    
-  <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
-    <property name="locations">
-      <list>
-        <value>classpath:persistence.properties</value>
-        <value>classpath:domains/*.properties</value>
-        <value>classpath:security.properties</value>
-        <value>classpath:connid.properties</value>
-        <value>classpath:mail.properties</value>
-        <value>classpath:workflow.properties</value>
-        <value>classpath:provisioning.properties</value>
-      </list>
-    </property>
-    <property name="ignoreResourceNotFound" value="true"/>
-    <property name="ignoreUnresolvablePlaceholders" value="true"/>
-  </bean>
-
-  <bean id="jwtIssuer" class="java.lang.String">
-    <constructor-arg value="${jwtIssuer}"/>
-  </bean>
-  <bean id="jwsKey" class="java.lang.String">
-    <constructor-arg value="${jwsKey}"/>
-  </bean>
-  <bean id="accessTokenJwsSignatureVerifier"
-        class="org.apache.syncope.core.spring.security.jws.AccessTokenJwsSignatureVerifier">
-    <property name="jwsAlgorithm" value="${jwsAlgorithm}"/>
-    <property name="jwsKey" value="${jwsKey}"/>
-  </bean>
-  <bean id="accessTokenJwsSignatureProvider"
-        class="org.apache.syncope.core.spring.security.jws.AccessTokenJwsSignatureProvider">
-    <property name="jwsAlgorithm" value="${jwsAlgorithm}"/>
-    <property name="jwsKey" value="${jwsKey}"/>
-  </bean>
-  <bean id="credentialChecker" class="org.apache.syncope.core.spring.security.DefaultCredentialChecker">
-    <constructor-arg value="${jwsKey}" index="0"/>
-    <constructor-arg value="${adminPassword}" index="1"/>
-    <constructor-arg value="${anonymousKey}" index="2"/>
-  </bean>
-  
-</beans>
diff --git a/core/spring/pom.xml b/core/spring/pom.xml
index f392628..5fe1334 100644
--- a/core/spring/pom.xml
+++ b/core/spring/pom.xml
@@ -60,11 +60,20 @@ under the License.
     </dependency>
 
     <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-autoconfigure</artifactId>
+    </dependency>
+
+    <dependency>
       <groupId>org.springframework.security</groupId>
       <artifactId>spring-security-core</artifactId>
     </dependency>
     <dependency>
       <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-config</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.security</groupId>
       <artifactId>spring-security-web</artifactId>
     </dependency>
     <dependency>
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/ApplicationContextProvider.java b/core/spring/src/main/java/org/apache/syncope/core/spring/ApplicationContextProvider.java
index a1ad7f1..f2919a7 100644
--- a/core/spring/src/main/java/org/apache/syncope/core/spring/ApplicationContextProvider.java
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/ApplicationContextProvider.java
@@ -33,6 +33,10 @@ public class ApplicationContextProvider implements ApplicationContextAware {
         return CTX;
     }
 
+    public static void setApplicationContext(final ConfigurableApplicationContext ctx) {
+        CTX = ctx;
+    }
+
     public static DefaultListableBeanFactory getBeanFactory() {
         return BEAN_FACTORY == null
                 ? CTX == null
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/Encryptor.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/Encryptor.java
index db36f44..0d39f59 100644
--- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/Encryptor.java
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/Encryptor.java
@@ -88,7 +88,7 @@ public final class Encryptor {
 
     static {
         try {
-            Properties props = PropertyUtils.read(Encryptor.class, "security.properties", "conf.directory").getLeft();
+            Properties props = PropertyUtils.read(Encryptor.class, "security.properties", "conf.directory");
 
             SECRET_KEY = props.getProperty("secretKey");
             SALT_ITERATIONS = Integer.valueOf(props.getProperty("digester.saltIterations"));
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecurityContext.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecurityContext.java
new file mode 100644
index 0000000..b7c44f2
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecurityContext.java
@@ -0,0 +1,124 @@
+/*
+ * 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.core.spring.security;
+
+import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.DefaultRolesPrefixPostProcessor;
+import org.apache.syncope.core.spring.security.jws.AccessTokenJwsSignatureProvider;
+import org.apache.syncope.core.spring.security.jws.AccessTokenJwsSignatureVerifier;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.ImportResource;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@ImportResource("classpath:/securityContext.xml")
+@PropertySource("classpath:security.properties")
+@PropertySource(value = "file:${conf.directory}/security.properties", ignoreResourceNotFound = true)
+@Configuration
+@EnableWebSecurity
+public class SecurityContext extends WebSecurityConfigurerAdapter implements EnvironmentAware {
+
+    private Environment env;
+
+    @Override
+    public void setEnvironment(final Environment env) {
+        this.env = env;
+    }
+
+    @Bean
+    public String adminUser() {
+        return env.getProperty("adminUser");
+    }
+
+    @Bean
+    public String adminPassword() {
+        return env.getProperty("adminPassword");
+    }
+
+    @Bean
+    public String adminPasswordAlgorithm() {
+        return env.getProperty("adminPasswordAlgorithm");
+    }
+
+    @Bean
+    public String anonymousUser() {
+        return env.getProperty("anonymousUser");
+    }
+
+    @Bean
+    public String anonymousKey() {
+        return env.getProperty("anonymousKey");
+    }
+
+    @Bean
+    public String jwtIssuer() {
+        return env.getProperty("jwtIssuer");
+    }
+
+    @Bean
+    public String jwsKey() {
+        return env.getProperty("jwsKey");
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public DefaultCredentialChecker credentialChecker() {
+        return new DefaultCredentialChecker(jwsKey(), adminPassword(), anonymousKey());
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public AccessTokenJwsSignatureVerifier accessTokenJwsSignatureVerifier() {
+        AccessTokenJwsSignatureVerifier verifier = new AccessTokenJwsSignatureVerifier();
+        verifier.setJwsAlgorithm(env.getProperty("jwsAlgorithm", SignatureAlgorithm.class));
+        verifier.setJwsKey(jwsKey());
+        return verifier;
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public AccessTokenJwsSignatureProvider accessTokenJwsSignatureProvider() {
+        AccessTokenJwsSignatureProvider provider = new AccessTokenJwsSignatureProvider();
+        provider.setJwsAlgorithm(env.getProperty("jwsAlgorithm", SignatureAlgorithm.class));
+        provider.setJwsKey(jwsKey());
+        return provider;
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public PasswordGenerator passwordGenerator() {
+        return new DefaultPasswordGenerator();
+    }
+
+    @Bean
+    public DefaultRolesPrefixPostProcessor rolesPrefixPostProcessor() {
+        return new DefaultRolesPrefixPostProcessor();
+    }
+
+    @Bean
+    public ApplicationContextProvider applicationContextProvider() {
+        return new ApplicationContextProvider();
+    }
+}
diff --git a/fit/core-reference/src/main/resources/logic.properties b/core/spring/src/main/resources/META-INF/spring.factories
similarity index 82%
copy from fit/core-reference/src/main/resources/logic.properties
copy to core/spring/src/main/resources/META-INF/spring.factories
index 802e7853..ebe786e 100644
--- a/fit/core-reference/src/main/resources/logic.properties
+++ b/core/spring/src/main/resources/META-INF/spring.factories
@@ -14,5 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-logicInvocationHandler=org.apache.syncope.core.logic.LogicInvocationHandler
-classPathScanImplementationLookup=org.apache.syncope.fit.core.reference.ITImplementationLookup
+
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  org.apache.syncope.core.spring.security.SecurityContext
diff --git a/core/spring/src/main/resources/securityContext.xml b/core/spring/src/main/resources/securityContext.xml
index bec0d12..a8e0c3d 100644
--- a/core/spring/src/main/resources/securityContext.xml
+++ b/core/spring/src/main/resources/securityContext.xml
@@ -24,53 +24,9 @@ under the License.
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/security
                            http://www.springframework.org/schema/security/spring-security.xsd">
-
-  <bean id="adminUser" class="java.lang.String">
-    <constructor-arg value="${adminUser}"/>
-  </bean>
-  <bean id="adminPassword" class="java.lang.String">
-    <constructor-arg value="${adminPassword}"/>
-  </bean>
-  <bean id="adminPasswordAlgorithm" class="java.lang.String">
-    <constructor-arg value="${adminPasswordAlgorithm}"/>
-  </bean>
-
-  <bean id="anonymousUser" class="java.lang.String">
-    <constructor-arg value="${anonymousUser}"/>
-  </bean>
-  <bean id="anonymousKey" class="java.lang.String">
-    <constructor-arg value="${anonymousKey}"/>
-  </bean>
-  
-  <bean id="jwtIssuer" class="java.lang.String">
-    <constructor-arg value="${jwtIssuer}"/>
-  </bean>
-  <bean id="jwsKey" class="java.lang.String">
-    <constructor-arg value="${jwsKey}"/>
-  </bean>
-
-  <bean id="credentialChecker" class="org.apache.syncope.core.spring.security.DefaultCredentialChecker">
-    <constructor-arg value="${jwsKey}" index="0"/>
-    <constructor-arg value="${adminPassword}" index="1"/>
-    <constructor-arg value="${anonymousKey}" index="2"/>
-  </bean>
-
-  <bean id="accessTokenJwsSignatureVerifier"
-        class="org.apache.syncope.core.spring.security.jws.AccessTokenJwsSignatureVerifier">
-    <property name="jwsAlgorithm" value="${jwsAlgorithm}"/>
-    <property name="jwsKey" value="${jwsKey}"/>
-  </bean>
-  <bean id="accessTokenJwsSignatureProvider"
-        class="org.apache.syncope.core.spring.security.jws.AccessTokenJwsSignatureProvider">
-    <property name="jwsAlgorithm" value="${jwsAlgorithm}"/>
-    <property name="jwsKey" value="${jwsKey}"/>
-  </bean>
-  
-  <bean class="${passwordGenerator}"/>
-  <bean class="org.apache.syncope.core.spring.DefaultRolesPrefixPostProcessor"/>
   
   <security:global-method-security pre-post-annotations="enabled"/>
-  
+
   <bean id="securityContextRepository" class='org.springframework.security.web.context.NullSecurityContextRepository'/>
   <bean id="securityContextPersistenceFilter"
         class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
@@ -138,4 +94,3 @@ under the License.
     <security:authentication-provider ref="jwtAuthenticationProvider"/>
   </security:authentication-manager>
 </beans>
-
diff --git a/core/spring/src/test/java/org/apache/syncope/core/spring/security/DummyImplementationLookup.java b/core/spring/src/test/java/org/apache/syncope/core/spring/security/DummyImplementationLookup.java
index 300220d..502067c 100644
--- a/core/spring/src/test/java/org/apache/syncope/core/spring/security/DummyImplementationLookup.java
+++ b/core/spring/src/test/java/org/apache/syncope/core/spring/security/DummyImplementationLookup.java
@@ -36,16 +36,11 @@ import org.apache.syncope.core.persistence.api.dao.Reportlet;
 public class DummyImplementationLookup implements ImplementationLookup {
 
     @Override
-    public Integer getPriority() {
+    public int getOrder() {
         return -1;
     }
 
     @Override
-    public void load() {
-        // do nothing
-    }
-
-    @Override
     public Set<String> getClassNames(final ImplementationType type) {
         return Collections.emptySet();
     }
diff --git a/core/spring/pom.xml b/core/starter/pom.xml
similarity index 61%
copy from core/spring/pom.xml
copy to core/starter/pom.xml
index f392628..f492545 100644
--- a/core/spring/pom.xml
+++ b/core/starter/pom.xml
@@ -27,88 +27,80 @@ under the License.
     <version>3.0.0-SNAPSHOT</version>
   </parent>
 
-  <name>Apache Syncope Core Spring</name>
-  <description>Apache Syncope Core Misc</description>
+  <name>Apache Syncope Core Spring Boot Starter</name>
+  <description>Apache Syncope Core Spring Boot Starter</description>
   <groupId>org.apache.syncope.core</groupId>
-  <artifactId>syncope-core-spring</artifactId>
+  <artifactId>syncope-core-starter</artifactId>
   <packaging>jar</packaging>
   
   <properties>
     <rootpom.basedir>${basedir}/../..</rootpom.basedir>
   </properties>
 
-  <dependencies>    
+  <dependencies>
     <dependency> 
       <groupId>javax.servlet</groupId> 
       <artifactId>javax.servlet-api</artifactId> 
       <scope>provided</scope>
     </dependency>
-    
+
     <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-spring-boot-starter-jaxrs</artifactId>
     </dependency>
-
     <dependency>
-      <groupId>org.jasypt</groupId>
-      <artifactId>jasypt</artifactId>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-log4j2</artifactId>
     </dependency>
-    
     <dependency>
-      <groupId>org.apache.cxf</groupId>
-      <artifactId>cxf-rt-rs-security-jose</artifactId>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-security</artifactId>
     </dependency>
-
+    
     <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-core</artifactId>
+      <groupId>org.apache.syncope.core.idrepo</groupId>
+      <artifactId>syncope-core-idrepo-rest-cxf</artifactId>
+      <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-web</artifactId>
+      <groupId>org.apache.syncope.core</groupId>
+      <artifactId>syncope-core-workflow-java</artifactId>
+      <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-tx</artifactId>
+      <groupId>org.apache.syncope.core</groupId>
+      <artifactId>syncope-core-persistence-jpa</artifactId>
+      <version>${project.version}</version>
     </dependency>
 
     <dependency>
-      <groupId>org.codehaus.groovy</groupId>
-      <artifactId>groovy</artifactId>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
     </dependency>
-
     <dependency>
-      <groupId>com.fasterxml.uuid</groupId>
-      <artifactId>java-uuid-generator</artifactId>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-api</artifactId>
     </dependency>
-
     <dependency>
-      <groupId>org.apache.syncope.core</groupId>
-      <artifactId>syncope-core-provisioning-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>        
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+    </dependency>
     <dependency>
-      <groupId>org.apache.syncope.common.idrepo</groupId>
-      <artifactId>syncope-common-idrepo-rest-api</artifactId>
-      <version>${project.version}</version>
+      <groupId>com.lmax</groupId>
+      <artifactId>disruptor</artifactId>
     </dependency>
-    
-    <!-- TEST -->
     <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-simple</artifactId>
-      <version>${slf4j.version}</version>
-      <scope>test</scope>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-test</artifactId>
-      <scope>test</scope>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <scope>provided</scope>
     </dependency>
     <dependency>
-      <groupId>org.junit.jupiter</groupId>
-      <artifactId>junit-jupiter-engine</artifactId>
-      <scope>test</scope>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
     </dependency>
   </dependencies>
 
@@ -119,22 +111,20 @@ under the License.
         <artifactId>maven-checkstyle-plugin</artifactId>
       </plugin>
     </plugins>
+
     <resources>
       <resource>
         <directory>src/main/resources</directory>
         <filtering>true</filtering>
-        <includes>
-          <include>**/security.properties</include>
-        </includes>
       </resource>
+      
       <resource>
-        <directory>src/main/resources</directory>
-        <filtering>false</filtering>
-        <excludes>
-          <exclude>**/security.properties</exclude>
-        </excludes>
+        <directory>${basedir}/../../src/main/resources</directory>
+        <filtering>true</filtering>
+        <includes>
+          <include>banner.txt</include>
+        </includes>
       </resource>
     </resources>
-
   </build>
 </project>
diff --git a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java b/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java
new file mode 100644
index 0000000..9350203
--- /dev/null
+++ b/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java
@@ -0,0 +1,58 @@
+/*
+ * 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.core.starter;
+
+import java.io.IOException;
+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.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
+import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
+import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@SpringBootApplication
+@EnableTransactionManagement
+@EnableAutoConfiguration(exclude = {
+    ErrorMvcAutoConfiguration.class,
+    HttpMessageConvertersAutoConfiguration.class,
+    DataSourceAutoConfiguration.class,
+    DataSourceTransactionManagerAutoConfiguration.class,
+    JdbcTemplateAutoConfiguration.class,
+    QuartzAutoConfiguration.class })
+public class SyncopeCoreApplication extends SpringBootServletInitializer {
+
+    public static void main(final String[] args) {
+        SpringApplication.run(SyncopeCoreApplication.class, args);
+    }
+
+    @Bean
+    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() throws IOException {
+        PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
+        pspc.setIgnoreResourceNotFound(true);
+        pspc.setIgnoreUnresolvablePlaceholders(true);
+        return pspc;
+    }
+}
diff --git a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreInitializer.java b/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreInitializer.java
new file mode 100644
index 0000000..5d4bb9e
--- /dev/null
+++ b/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreInitializer.java
@@ -0,0 +1,69 @@
+/*
+ * 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.core.starter;
+
+import java.util.Comparator;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
+import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.aop.support.AopUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.core.Ordered;
+import org.springframework.stereotype.Component;
+
+/**
+ * Take care of all initializations needed by Syncope Core to run up and safe.
+ */
+@Component
+public class SyncopeCoreInitializer implements ApplicationListener<ContextRefreshedEvent>, Ordered {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SyncopeCoreInitializer.class);
+
+    @Autowired
+    private DomainsHolder domainsHolder;
+
+    @Override
+    public int getOrder() {
+        return 0;
+    }
+
+    @Override
+    public void onApplicationEvent(final ContextRefreshedEvent event) {
+        event.getApplicationContext().getBeansOfType(SyncopeCoreLoader.class).values().stream().
+                sorted(Comparator.comparing(SyncopeCoreLoader::getOrder)).
+                forEach(loader -> {
+                    String loaderName = AopUtils.getTargetClass(loader).getName();
+
+                    LOG.debug("[{}] Starting initialization", loaderName);
+
+                    loader.load();
+
+                    domainsHolder.getDomains().forEach((domain, datasource) -> {
+                        LOG.debug("[{}] Starting on domain '{}'", loaderName, domain);
+                        loader.load(domain, datasource);
+                        LOG.debug("[{}] Completed on domain '{}'", loaderName, domain);
+                    });
+
+                    LOG.debug("[{}] Initialization completed", loaderName);
+                });
+    }
+}
diff --git a/fit/core-reference/src/main/resources/all/saml2sp-logic.properties b/core/starter/src/main/resources/application.properties
similarity index 73%
copy from fit/core-reference/src/main/resources/all/saml2sp-logic.properties
copy to core/starter/src/main/resources/application.properties
index fc99f62..4be1989 100644
--- a/fit/core-reference/src/main/resources/all/saml2sp-logic.properties
+++ b/core/starter/src/main/resources/application.properties
@@ -14,11 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+spring.application.name=Apache Syncope ${syncope.version} Core
+spring.groovy.template.check-template-location=false
+spring.main.banner-mode=log
+
+spring.http.encoding.charset=UTF-8
+spring.http.encoding.enabled=true
+spring.http.encoding.force=true
+
 conf.directory=${conf.directory}
 
-keystore.name=keystore
-keystore.type=jks
-keystore.storepass=changeit
-keystore.keypass=changeit
-sp.cert.alias=sp
-signature.algorithm=RSA_SHA1
\ No newline at end of file
+server.servlet.contextPath=/syncope
+cxf.path=/rest
diff --git a/core/upgrade/pom.xml b/core/upgrade/pom.xml
index 92ecf90..a7380a3 100644
--- a/core/upgrade/pom.xml
+++ b/core/upgrade/pom.xml
@@ -108,7 +108,7 @@ under the License.
         </configuration>
         <executions>
           <execution>
-            <id>make-cli-zip</id>
+            <id>make-upgrade-zip</id>
             <phase>verify</phase>
             <goals>
               <goal>single</goal>
diff --git a/core/upgrade/src/assemble/upgrade-zip.xml b/core/upgrade/src/assemble/upgrade-zip.xml
index d39fb6c..b891fd2 100644
--- a/core/upgrade/src/assemble/upgrade-zip.xml
+++ b/core/upgrade/src/assemble/upgrade-zip.xml
@@ -17,12 +17,12 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 -->
-<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 
-                              http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0
+                              http://maven.apache.org/xsd/assembly-2.0.0.xsd">
 
-  <id>cli</id>
+  <id>upgrade-zip</id>
   
   <formats>
     <format>zip</format>
@@ -40,7 +40,7 @@ under the License.
       <outputDirectory>${project.build.finalName}</outputDirectory>
     </fileSet>
     <fileSet>
-      <directory>${project.build.directory}/classes</directory>
+      <directory>${project.build.outputDirectory}</directory>
       <includes>
         <include>syncopeupgrade.sh</include>
         <include>syncopeupgrade.bat</include>
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/WorkflowContext.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/WorkflowContext.java
new file mode 100644
index 0000000..aa05c53
--- /dev/null
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/WorkflowContext.java
@@ -0,0 +1,65 @@
+/*
+ * 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.core.workflow.java;
+
+import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
+import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
+import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+
+@PropertySource("classpath:workflow.properties")
+@PropertySource(value = "file:${conf.directory}/workflow.properties", ignoreResourceNotFound = true)
+@Configuration
+public class WorkflowContext implements EnvironmentAware {
+
+    private Environment env;
+
+    @Override
+    public void setEnvironment(final Environment env) {
+        this.env = env;
+    }
+
+    @Bean
+    public UserWorkflowAdapter uwfAdapter()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (UserWorkflowAdapter) Class.forName(env.getProperty("uwfAdapter")).
+                newInstance();
+    }
+
+    @Bean
+    public GroupWorkflowAdapter gwfAdapter()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (GroupWorkflowAdapter) Class.forName(env.getProperty("gwfAdapter")).
+                newInstance();
+    }
+
+    @Bean
+    public AnyObjectWorkflowAdapter awfAdapter()
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        return (AnyObjectWorkflowAdapter) Class.forName(env.getProperty("awfAdapter")).
+                newInstance();
+    }
+}
diff --git a/fit/core-reference/src/main/resources/logic.properties b/core/workflow-java/src/main/resources/META-INF/spring.factories
similarity index 82%
copy from fit/core-reference/src/main/resources/logic.properties
copy to core/workflow-java/src/main/resources/META-INF/spring.factories
index 802e7853..b7b90b1 100644
--- a/fit/core-reference/src/main/resources/logic.properties
+++ b/core/workflow-java/src/main/resources/META-INF/spring.factories
@@ -14,5 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-logicInvocationHandler=org.apache.syncope.core.logic.LogicInvocationHandler
-classPathScanImplementationLookup=org.apache.syncope.fit.core.reference.ITImplementationLookup
+
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  org.apache.syncope.core.workflow.java.WorkflowContext
diff --git a/core/workflow-java/src/main/resources/workflowContext.xml b/core/workflow-java/src/main/resources/workflowContext.xml
deleted file mode 100644
index 8db5e17..0000000
--- a/core/workflow-java/src/main/resources/workflowContext.xml
+++ /dev/null
@@ -1,29 +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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans   
-                           http://www.springframework.org/schema/beans/spring-beans.xsd">
-
-  <bean id="uwfAdapter" class="${uwfAdapter}"/>
-  <bean id="gwfAdapter" class="${gwfAdapter}"/>
-  <bean id="awfAdapter" class="${awfAdapter}"/>
-    
-</beans>
diff --git a/deb/console/pom.xml b/deb/console/pom.xml
index cd63a0e..77da3c5 100644
--- a/deb/console/pom.xml
+++ b/deb/console/pom.xml
@@ -48,57 +48,31 @@ under the License.
       <groupId>org.apache.syncope.ext.flowable</groupId>
       <artifactId>syncope-ext-flowable-client-console</artifactId>
       <version>${project.version}</version>
-    </dependency>    
+    </dependency>
+
     <dependency>
       <groupId>org.apache.syncope.ext.camel</groupId>
       <artifactId>syncope-ext-camel-client-console</artifactId>
       <version>${project.version}</version>
-    </dependency>    
+    </dependency>
+
     <dependency>
       <groupId>org.apache.syncope.ext.saml2sp</groupId>
       <artifactId>syncope-ext-saml2sp-client-console</artifactId>
       <version>${project.version}</version>
     </dependency>
+
     <dependency>
       <groupId>org.apache.syncope.ext.oidcclient</groupId>
       <artifactId>syncope-ext-oidcclient-client-console</artifactId>
       <version>${project.version}</version>
     </dependency>
+
     <dependency>
       <groupId>org.apache.syncope.ext.scimv2</groupId>
       <artifactId>syncope-ext-scimv2-client-console</artifactId>
       <version>${project.version}</version>
     </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>
   </dependencies>
 
   <build>
@@ -110,7 +84,14 @@ under the License.
       </resource>
       
       <resource>
-        <directory>${project.basedir}/../../client/console/src/main/resources</directory>
+        <directory>${project.basedir}/../../client/idrepo/console/src/main/resources</directory>
+        <includes>
+          <include>application.properties</include>
+        </includes>
+        <filtering>true</filtering>
+      </resource>
+      <resource>
+        <directory>${project.basedir}/../../client/idrepo/console/src/main/resources</directory>
         <includes>
           <include>console.properties</include>
         </includes>
@@ -138,13 +119,13 @@ under the License.
         <includes>
           <include>log4j2.xml</include>
         </includes>
-        <targetPath>${project.build.directory}/classes</targetPath>
+        <targetPath>${project.build.outputDirectory}</targetPath>
         <filtering>true</filtering>
       </resource>
       
       <resource>
         <directory>${project.build.directory}/etc</directory>
-        <targetPath>${project.build.directory}/classes</targetPath>
+        <targetPath>${project.build.outputDirectory}</targetPath>
       </resource>
       
       <resource>
@@ -247,6 +228,7 @@ under the License.
                 <data>
                   <src>${project.build.directory}/etc</src>
                   <type>directory</type>
+                  <conffile>true</conffile>
                   <mapper>
                     <type>perm</type>
                     <prefix>${conf.directory}</prefix>
diff --git a/deb/console/src/deb/control/conffiles b/deb/console/src/deb/control/conffiles
deleted file mode 100644
index a9bfb08..0000000
--- a/deb/console/src/deb/control/conffiles
+++ /dev/null
@@ -1,5 +0,0 @@
-/etc/tomcat8/Catalina/localhost/syncope-console.xml
-/etc/apache-syncope/console.properties
-/etc/apache-syncope/saml2sp-agent.properties
-/etc/apache-syncope/oidcclient-agent.properties
-
diff --git a/deb/core/pom.xml b/deb/core/pom.xml
index 865950e..85c88c8 100644
--- a/deb/core/pom.xml
+++ b/deb/core/pom.xml
@@ -39,18 +39,19 @@ under the License.
   
   <dependencies>
     <dependency>
-      <groupId>org.apache.syncope.core.idm</groupId>
-      <artifactId>syncope-core-idm-rest-cxf</artifactId>
+      <groupId>org.apache.syncope.core</groupId>
+      <artifactId>syncope-core-starter</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.core</groupId>
-      <artifactId>syncope-core-workflow-java</artifactId>
+      <groupId>org.apache.syncope.core.idm</groupId>
+      <artifactId>syncope-core-idm-rest-cxf</artifactId>
       <version>${project.version}</version>
     </dependency>
+
     <dependency>
       <groupId>org.apache.syncope.core</groupId>
-      <artifactId>syncope-core-persistence-jpa</artifactId>
+      <artifactId>syncope-core-persistence-jpa-json</artifactId>
       <version>${project.version}</version>
     </dependency>
     
@@ -114,36 +115,6 @@ under the License.
       <artifactId>syncope-ext-swagger-ui</artifactId>
       <version>${project.version}</version>
     </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>
   </dependencies>
 
   <build>
@@ -155,8 +126,18 @@ under the License.
       </resource>
       
       <resource>
-        <directory>${basedir}/../../core/persistence-jpa/src/main/resources/domains</directory>
-        <targetPath>${project.build.directory}/etc/domains</targetPath>
+        <directory>${basedir}/../../core/starter/src/main/resources</directory>
+        <includes>
+          <include>application.properties</include>
+        </includes>
+        <filtering>true</filtering>
+      </resource>
+      <resource>
+        <directory>${basedir}/../../core/spring/src/main/resources</directory>
+        <includes>
+          <include>security.properties</include>
+        </includes>
+        <targetPath>${project.build.directory}/etc</targetPath>
         <filtering>true</filtering>
       </resource>
       <resource>
@@ -189,58 +170,56 @@ under the License.
         <filtering>true</filtering>
       </resource>
       <resource>
-        <directory>${basedir}/../../core/spring/src/main/resources</directory>
+        <directory>${basedir}/../../core/idrepo/logic/src/main/resources</directory>
         <includes>
-          <include>security.properties</include>
+          <include>logic.properties</include>
         </includes>
         <targetPath>${project.build.directory}/etc</targetPath>
         <filtering>true</filtering>
       </resource>
       <resource>
-        <directory>${basedir}/../../core/logic/src/main/resources</directory>
+        <directory>${project.basedir}/../../ext/saml2sp/logic/src/main/resources</directory>
         <includes>
-          <include>logic.properties</include>
+          <include>saml2sp-logic.properties</include>
         </includes>
         <targetPath>${project.build.directory}/etc</targetPath>
         <filtering>true</filtering>
       </resource>
       <resource>
-        <directory>${basedir}/../../fit/core-reference/src/main/resources</directory>
+        <directory>${basedir}/../../fit/core-reference/src/test/resources</directory>
         <includes>
-          <include>coreContext.xml</include>
-          <include>log4j2.xml</include>
+          <include>keystore</include>
         </includes>
         <targetPath>${project.build.directory}/etc</targetPath>
-        <filtering>true</filtering>
+        <filtering>false</filtering>
       </resource>
       <resource>
-        <directory>${basedir}/../../fit/core-reference/src/main/resources/postgres</directory>
+        <directory>${basedir}/../../fit/core-reference/src/main/resources</directory>
         <includes>
-          <include>views.xml</include>
+          <include>log4j2.xml</include>
         </includes>
         <targetPath>${project.build.directory}/etc</targetPath>
         <filtering>true</filtering>
       </resource>
       <resource>
-        <directory>${project.basedir}/../../ext/saml2sp/logic/src/main/resources</directory>
+        <directory>${basedir}/../../core/persistence-jpa-json/src/main/resources/pgjsonb</directory>
         <includes>
-          <include>saml2sp-logic.properties</include>
+          <include>persistence.properties</include>
+          <include>indexes.xml</include>
+          <include>views.xml</include>        
         </includes>
         <targetPath>${project.build.directory}/etc</targetPath>
         <filtering>true</filtering>
       </resource>
       <resource>
-        <directory>${basedir}/../../fit/core-reference/src/test/resources</directory>
-        <includes>
-          <include>keystore</include>
-        </includes>
-        <targetPath>${project.build.directory}/etc</targetPath>
-        <filtering>false</filtering>
+        <directory>${basedir}/../../core/persistence-jpa-json/src/main/resources/pgjsonb/domains</directory>
+        <targetPath>${project.build.directory}/etc/domains</targetPath>
+        <filtering>true</filtering>
       </resource>
 
       <resource>
         <directory>${project.build.directory}/etc</directory>
-        <targetPath>${project.build.directory}/classes</targetPath>
+        <targetPath>${project.build.outputDirectory}</targetPath>
       </resource>
       
       <resource>
@@ -361,6 +340,7 @@ under the License.
                 <data>
                   <src>${project.build.directory}/etc</src>
                   <type>directory</type>
+                  <conffile>true</conffile>
                   <mapper>
                     <type>perm</type>
                     <prefix>${conf.directory}</prefix>
diff --git a/deb/core/src/deb/control/conffiles b/deb/core/src/deb/control/conffiles
deleted file mode 100644
index 1dc06a7..0000000
--- a/deb/core/src/deb/control/conffiles
+++ /dev/null
@@ -1,15 +0,0 @@
-/etc/tomcat8/Catalina/localhost/syncope.xml
-/etc/apache-syncope/connid.properties
-/etc/apache-syncope/content.xml
-/etc/apache-syncope/coreContext.xml
-/etc/apache-syncope/log4j2.xml
-/etc/apache-syncope/logic.properties
-/etc/apache-syncope/mail.properties
-/etc/apache-syncope/persistence.properties
-/etc/apache-syncope/provisioning.properties
-/etc/apache-syncope/groupRoutes.xml
-/etc/apache-syncope/saml2sp-logic.properties
-/etc/apache-syncope/security.properties
-/etc/apache-syncope/userRoutes.xml
-/etc/apache-syncope/userWorkflow.bpmn20.xml
-/etc/apache-syncope/workflow.properties
diff --git a/deb/core/src/deb/tomcat8/syncope.xml b/deb/core/src/deb/tomcat8/syncope.xml
index b06a129..7e5dc2a 100644
--- a/deb/core/src/deb/tomcat8/syncope.xml
+++ b/deb/core/src/deb/tomcat8/syncope.xml
@@ -32,7 +32,7 @@ under the License.
               maxWait="-1"/>
   -->
 
-  <!--  https://cwiki.apache.org/confluence/display/SYNCOPE/Run+Syncope+in+real+environments
+  <!--  http://syncope.apache.org/docs/reference-guide.html#apache-tomcat-9
 
    <Resource name="jdbc/syncopeMasterDataSource" auth="Container" type="javax.sql.DataSource"
       factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" testWhileIdle="true"
diff --git a/deb/enduser/pom.xml b/deb/enduser/pom.xml
index cd882b7..c21b7ba 100644
--- a/deb/enduser/pom.xml
+++ b/deb/enduser/pom.xml
@@ -61,36 +61,6 @@ under the License.
       <artifactId>syncope-ext-oidcclient-client-enduser</artifactId>
       <version>${project.version}</version>
     </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>
   </dependencies>
 
   <build>
@@ -104,6 +74,7 @@ under the License.
       <resource>
         <directory>${project.basedir}/../../client/enduser/src/main/resources</directory>
         <includes>
+          <include>application.properties</include>
           <include>enduser.properties</include>
           <include>customFormAttributes.json</include>
           <include>customTemplate.json</include>
@@ -132,13 +103,13 @@ under the License.
         <includes>
           <include>log4j2.xml</include>
         </includes>
-        <targetPath>${project.build.directory}/classes</targetPath>
+        <targetPath>${project.build.outputDirectory}</targetPath>
         <filtering>true</filtering>
       </resource>
       
       <resource>
         <directory>${project.build.directory}/etc</directory>
-        <targetPath>${project.build.directory}/classes</targetPath>
+        <targetPath>${project.build.outputDirectory}</targetPath>
       </resource>
       
       <resource>
@@ -241,6 +212,7 @@ under the License.
                 <data>
                   <src>${project.build.directory}/etc</src>
                   <type>directory</type>
+                  <conffile>true</conffile>
                   <mapper>
                     <type>perm</type>
                     <prefix>${conf.directory}</prefix>
@@ -311,5 +283,5 @@ under the License.
       </build>
     </profile>
   </profiles>
-  
+
 </project>
diff --git a/deb/enduser/src/deb/control/conffiles b/deb/enduser/src/deb/control/conffiles
deleted file mode 100644
index d115b8e..0000000
--- a/deb/enduser/src/deb/control/conffiles
+++ /dev/null
@@ -1,7 +0,0 @@
-/etc/tomcat8/Catalina/localhost/syncope-enduser.xml
-/etc/apache-syncope/enduser.properties
-/etc/apache-syncope/customFormAttributes.json
-/etc/apache-syncope/customTemplate.json
-/etc/apache-syncope/saml2sp-agent.properties
-/etc/apache-syncope/oidcclient-agent.properties
-
diff --git a/docker/console/LICENSE b/docker/console/LICENSE
new file mode 100644
index 0000000..99b82d1
--- /dev/null
+++ b/docker/console/LICENSE
@@ -0,0 +1,889 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
+==
+
+For Animate.css (http://daneden.github.io/animate.css/):
+This is licensed under the MIT license:
+
+ Permission is hereby granted, free  of charge, to any person obtaining
+ a  copy  of this  software  and  associated  documentation files  (the
+ "Software"), to  deal in  the Software without  restriction, including
+ without limitation  the rights to  use, copy, modify,  merge, publish,
+ distribute,  sublicense, and/or sell  copies of  the Software,  and to
+ permit persons to whom the Software  is furnished to do so, subject to
+ the following conditions:
+ 
+ The  above  copyright  notice  and  this permission  notice  shall  be
+ included in all copies or substantial portions of the Software.
+ 
+ THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
+ EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
+ MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+==
+
+For Bootbox.js (http://bootboxjs.com/):
+This is licensed under the MIT license, see above.
+
+==
+
+For Bootstrap (http://getbootstrap.com/):
+This is licensed under the MIT license, see above.
+
+==
+
+For CodeMirror (http://codemirror.net/):
+This is licensed under the MIT license, see above.
+
+==
+
+For Jackson (http://wiki.fasterxml.com/JacksonHome):
+This is licensed under the AL 2.0, see above.
+
+==
+
+For Guava (https://github.com/google/guava):
+This is licensed under the AL 2.0, see above.
+
+==
+
+For Wicket - jQuery UI (http://www.7thweb.net/wicket-jquery-ui/):
+This is licensed under the AL 2.0, see above.
+
+==
+
+For LMAX Disruptor (https://lmax-exchange.github.io/disruptor/):
+This is licensed under the AL 2.0, see above.
+
+==
+
+For JAX-B (http://jaxb.java.net/):
+This is licensed under the CDDL 1.0:
+
+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+
+1. Definitions.
+
+1.1. "Contributor" means each individual or entity that
+creates or contributes to the creation of Modifications.
+
+1.2. "Contributor Version" means the combination of the
+Original Software, prior Modifications used by a
+Contributor (if any), and the Modifications made by that
+particular Contributor.
+
+1.3. "Covered Software" means (a) the Original Software, or
+(b) Modifications, or (c) the combination of files
+containing Original Software with files containing
+Modifications, in each case including portions thereof.
+
+1.4. "Executable" means the Covered Software in any form
+other than Source Code.
+
+1.5. "Initial Developer" means the individual or entity
+that first makes Original Software available under this
+License.
+
+1.6. "Larger Work" means a work which combines Covered
+Software or portions thereof with code not governed by the
+terms of this License.
+
+1.7. "License" means this document.
+
+1.8. "Licensable" means having the right to grant, to the
+maximum extent possible, whether at the time of the initial
+grant or subsequently acquired, any and all of the rights
+conveyed herein.
+
+1.9. "Modifications" means the Source Code and Executable
+form of any of the following:
+
+A. Any file that results from an addition to,
+deletion from or modification of the contents of a
+file containing Original Software or previous
+Modifications;
+
+B. Any new file that contains any part of the
+Original Software or previous Modification; or
+
+C. Any new file that is contributed or otherwise made
+available under the terms of this License.
+
+1.10. "Original Software" means the Source Code and
+Executable form of computer software code that is
+originally released under this License.
+
+1.11. "Patent Claims" means any patent claim(s), now owned
+or hereafter acquired, including without limitation,
+method, process, and apparatus claims, in any patent
+Licensable by grantor.
+
+1.12. "Source Code" means (a) the common form of computer
+software code in which modifications are made and (b)
+associated documentation included in or with such code.
+
+1.13. "You" (or "Your") means an individual or a legal
+entity exercising rights under, and complying with all of
+the terms of, this License. For legal entities, "You"
+includes any entity which controls, is controlled by, or is
+under common control with You. For purposes of this
+definition, "control" means (a) the power, direct or
+indirect, to cause the direction or management of such
+entity, whether by contract or otherwise, or (b) ownership
+of more than fifty percent (50%) of the outstanding shares
+or beneficial ownership of such entity.
+
+2. License Grants.
+
+2.1. The Initial Developer Grant.
+
+Conditioned upon Your compliance with Section 3.1 below and
+subject to third party intellectual property claims, the
+Initial Developer hereby grants You a world-wide,
+royalty-free, non-exclusive license:
+
+(a) under intellectual property rights (other than
+patent or trademark) Licensable by Initial Developer,
+to use, reproduce, modify, display, perform,
+sublicense and distribute the Original Software (or
+portions thereof), with or without Modifications,
+and/or as part of a Larger Work; and
+
+(b) under Patent Claims infringed by the making,
+using or selling of Original Software, to make, have
+made, use, practice, sell, and offer for sale, and/or
+otherwise dispose of the Original Software (or
+portions thereof).
+
+(c) The licenses granted in Sections 2.1(a) and (b)
+are effective on the date Initial Developer first
+distributes or otherwise makes the Original Software
+available to a third party under the terms of this
+License.
+
+(d) Notwithstanding Section 2.1(b) above, no patent
+license is granted: (1) for code that You delete from
+the Original Software, or (2) for infringements
+caused by: (i) the modification of the Original
+Software, or (ii) the combination of the Original
+Software with other software or devices.
+
+2.2. Contributor Grant.
+
+Conditioned upon Your compliance with Section 3.1 below and
+subject to third party intellectual property claims, each
+Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than
+patent or trademark) Licensable by Contributor to
+use, reproduce, modify, display, perform, sublicense
+and distribute the Modifications created by such
+Contributor (or portions thereof), either on an
+unmodified basis, with other Modifications, as
+Covered Software and/or as part of a Larger Work; and
+
+(b) under Patent Claims infringed by the making,
+using, or selling of Modifications made by that
+Contributor either alone and/or in combination with
+its Contributor Version (or portions of such
+combination), to make, use, sell, offer for sale,
+have made, and/or otherwise dispose of: (1)
+Modifications made by that Contributor (or portions
+thereof); and (2) the combination of Modifications
+made by that Contributor with its Contributor Version
+(or portions of such combination).
+
+(c) The licenses granted in Sections 2.2(a) and
+2.2(b) are effective on the date Contributor first
+distributes or otherwise makes the Modifications
+available to a third party.
+
+(d) Notwithstanding Section 2.2(b) above, no patent
+license is granted: (1) for any code that Contributor
+has deleted from the Contributor Version; (2) for
+infringements caused by: (i) third party
+modifications of Contributor Version, or (ii) the
+combination of Modifications made by that Contributor
+with other software (except as part of the
+Contributor Version) or other devices; or (3) under
+Patent Claims infringed by Covered Software in the
+absence of Modifications made by that Contributor.
+
+3. Distribution Obligations.
+
+3.1. Availability of Source Code.
+
+Any Covered Software that You distribute or otherwise make
+available in Executable form must also be made available in
+Source Code form and that Source Code form must be
+distributed only under the terms of this License. You must
+include a copy of this License with every copy of the
+Source Code form of the Covered Software You distribute or
+otherwise make available. You must inform recipients of any
+such Covered Software in Executable form as to how they can
+obtain such Covered Software in Source Code form in a
+reasonable manner on or through a medium customarily used
+for software exchange.
+
+3.2. Modifications.
+
+The Modifications that You create or to which You
+contribute are governed by the terms of this License. You
+represent that You believe Your Modifications are Your
+original creation(s) and/or You have sufficient rights to
+grant the rights conveyed by this License.
+
+3.3. Required Notices.
+
+You must include a notice in each of Your Modifications
+that identifies You as the Contributor of the Modification.
+You may not remove or alter any copyright, patent or
+trademark notices contained within the Covered Software, or
+any notices of licensing or any descriptive text giving
+attribution to any Contributor or the Initial Developer.
+
+3.4. Application of Additional Terms.
+
+You may not offer or impose any terms on any Covered
+Software in Source Code form that alters or restricts the
+applicable version of this License or the recipients'
+rights hereunder. You may choose to offer, and to charge a
+fee for, warranty, support, indemnity or liability
+obligations to one or more recipients of Covered Software.
+However, you may do so only on Your own behalf, and not on
+behalf of the Initial Developer or any Contributor. You
+must make it absolutely clear that any such warranty,
+support, indemnity or liability obligation is offered by
+You alone, and You hereby agree to indemnify the Initial
+Developer and every Contributor for any liability incurred
+by the Initial Developer or such Contributor as a result of
+warranty, support, indemnity or liability terms You offer.
+
+3.5. Distribution of Executable Versions.
+
+You may distribute the Executable form of the Covered
+Software under the terms of this License or under the terms
+of a license of Your choice, which may contain terms
+different from this License, provided that You are in
+compliance with the terms of this License and that the
+license for the Executable form does not attempt to limit
+or alter the recipient's rights in the Source Code form
+from the rights set forth in this License. If You
+distribute the Covered Software in Executable form under a
+different license, You must make it absolutely clear that
+any terms which differ from this License are offered by You
+alone, not by the Initial Developer or Contributor. You
+hereby agree to indemnify the Initial Developer and every
+Contributor for any liability incurred by the Initial
+Developer or such Contributor as a result of any such terms
+You offer.
+
+3.6. Larger Works.
+
+You may create a Larger Work by combining Covered Software
+with other code not governed by the terms of this License
+and distribute the Larger Work as a single product. In such
+a case, You must make sure the requirements of this License
+are fulfilled for the Covered Software.
+
+4. Versions of the License.
+
+4.1. New Versions.
+
+Sun Microsystems, Inc. is the initial license steward and
+may publish revised and/or new versions of this License
+from time to time. Each version will be given a
+distinguishing version number. Except as provided in
+Section 4.3, no one other than the license steward has the
+right to modify this License.
+
+4.2. Effect of New Versions.
+
+You may always continue to use, distribute or otherwise
+make the Covered Software available under the terms of the
+version of the License under which You originally received
+the Covered Software. If the Initial Developer includes a
+notice in the Original Software prohibiting it from being
+distributed or otherwise made available under any
+subsequent version of the License, You must distribute and
+make the Covered Software available under the terms of the
+version of the License under which You originally received
+the Covered Software. Otherwise, You may also choose to
+use, distribute or otherwise make the Covered Software
+available under the terms of any subsequent version of the
+License published by the license steward.
+
+4.3. Modified Versions.
+
+When You are an Initial Developer and You want to create a
+new license for Your Original Software, You may create and
+use a modified version of this License if You: (a) rename
+the license and remove any references to the name of the
+license steward (except to note that the license differs
+from this License); and (b) otherwise make it clear that
+the license contains terms which differ from this License.
+
+5. DISCLAIMER OF WARRANTY.
+
+COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS"
+BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED
+SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR
+PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY
+COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
+INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF
+ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF
+WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
+DISCLAIMER.
+
+6. TERMINATION.
+
+6.1. This License and the rights granted hereunder will
+terminate automatically if You fail to comply with terms
+herein and fail to cure such breach within 30 days of
+becoming aware of the breach. Provisions which, by their
+nature, must remain in effect beyond the termination of
+this License shall survive.
+
+6.2. If You assert a patent infringement claim (excluding
+declaratory judgment actions) against Initial Developer or
+a Contributor (the Initial Developer or Contributor against
+whom You assert such claim is referred to as "Participant")
+alleging that the Participant Software (meaning the
+Contributor Version where the Participant is a Contributor
+or the Original Software where the Participant is the
+Initial Developer) directly or indirectly infringes any
+patent, then any and all rights granted directly or
+indirectly to You by such Participant, the Initial
+Developer (if the Initial Developer is not the Participant)
+and all Contributors under Sections 2.1 and/or 2.2 of this
+License shall, upon 60 days notice from Participant
+terminate prospectively and automatically at the expiration
+of such 60 day notice period, unless if within such 60 day
+period You withdraw Your claim with respect to the
+Participant Software against such Participant either
+unilaterally or pursuant to a written agreement with
+Participant.
+
+6.3. In the event of termination under Sections 6.1 or 6.2
+above, all end user licenses that have been validly granted
+by You or any distributor hereunder prior to termination
+(excluding licenses granted to You by any distributor)
+shall survive termination.
+
+7. LIMITATION OF LIABILITY.
+
+UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+(INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE
+INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF
+COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE
+LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
+CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
+LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK
+STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
+INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT
+APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO
+NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
+CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT
+APPLY TO YOU.
+
+8. U.S. GOVERNMENT END USERS.
+
+The Covered Software is a "commercial item," as that term is
+defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial
+computer software" (as that term is defined at 48 C.F.R. $
+252.227-7014(a)(1)) and "commercial computer software
+documentation" as such terms are used in 48 C.F.R. 12.212 (Sept.
+1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1
+through 227.7202-4 (June 1995), all U.S. Government End Users
+acquire Covered Software with only those rights set forth herein.
+This U.S. Government Rights clause is in lieu of, and supersedes,
+any other FAR, DFAR, or other clause or provision that addresses
+Government rights in computer software under this License.
+
+9. MISCELLANEOUS.
+
+This License represents the complete agreement concerning subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the
+extent necessary to make it enforceable. This License shall be
+governed by the law of the jurisdiction specified in a notice
+contained within the Original Software (except to the extent
+applicable law, if any, provides otherwise), excluding such
+jurisdiction's conflict-of-law provisions. Any litigation
+relating to this License shall be subject to the jurisdiction of
+the courts located in the jurisdiction and venue specified in a
+notice contained within the Original Software, with the losing
+party responsible for costs, including, without limitation, court
+costs and reasonable attorneys' fees and expenses. The
+application of the United Nations Convention on Contracts for the
+International Sale of Goods is expressly excluded. Any law or
+regulation which provides that the language of a contract shall
+be construed against the drafter shall not apply to this License.
+You agree that You alone are responsible for compliance with the
+United States export administration regulations (and the export
+control laws and regulation of any other countries) when You use,
+distribute or otherwise make available any Covered Software.
+
+10. RESPONSIBILITY FOR CLAIMS.
+
+As between Initial Developer and the Contributors, each party is
+responsible for claims and damages arising, directly or
+indirectly, out of its utilization of rights under this License
+and You agree to work with Initial Developer and Contributors to
+distribute such responsibility on an equitable basis. Nothing
+herein is intended or shall be deemed to constitute any admission
+of liability.
+
+==
+
+For Font Awesome (http://fontawesome.io/):
+This is licensed under the MIT license, see above.
+
+==
+
+For google-diff-match-patch (https://code.google.com/archive/p/google-diff-match-patch/):
+This is licensed under the AL 2.0, see above.
+
+==
+
+For Swagger (http://swagger.io/):
+This is licensed under the AL 2.0, see above.
+
+==
+
+For Ionicons (http://ionicons.com/):
+This is licensed under the MIT license, see above.
+
+==
+
+For slimScroll (http://rocha.la/jQuery-slimScroll):
+This is licensed under the MIT license, see above.
+
+==
+
+For javax.annotation-api (https://jcp.org/en/jsr/detail?id=250):
+This is licensed under the CDDL 1.0, see above.
+
+==
+
+For Bean Validation API (http://beanvalidation.org/):
+This is licensed under the AL 2.0, see above.
+
+==
+
+For javax.ws.rs-api (https://jax-rs-spec.java.net/):
+This is licensed under the CDDL 1.0, see above.
+
+==
+
+For Joda Time (http://www.joda.org/joda-time/):
+This is licensed under the AL 2.0, see above.
+
+==
+
+For jQuery (http://jquery.com/):
+This is licensed under the MIT license, see above.
+
+==
+
+For jquery.cookie (https://github.com/carhartl/jquery-cookie):
+This is licensed under the MIT license, see above.
+
+==
+
+For jQuery UI (http://jqueryui.com/):
+This is licensed under the MIT license, see above.
+
+==
+
+For jQuery++ (http://jquerypp.com/):
+This is licensed under the MIT license, see above.
+
+==
+
+For jsPlumb (http://jsplumbtoolkit.com/):
+This is licensed under the MIT license, see above.
+
+==
+
+For Modernizr (https://modernizr.com):
+This is licensed under the MIT license, see above.
+
+==
+
+For StAX2 API (http://wiki.fasterxml.com/WoodstoxStax2):
+This is licensed under the BSD license:
+
+Redistribution and use in source and binary forms, with or without 
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this 
+list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, 
+this list of conditions and the following disclaimer in the documentation 
+and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors 
+may be used to endorse or promote products derived from this software without 
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+==
+
+For Woodstox (http://wiki.fasterxml.com/WoodstoxHome):
+This is licensed under the AL 2.0, see above.
+
+==
+
+For Simple Logging Facade for Java - SLF4J (http://www.slf4j.org/):
+This is licensed under the MIT license, see above.
+
+==
+
+For Spring Framework (http://projects.spring.io/spring-framework/):
+This is licensed under the AL 2.0, see above.
+
+==
+
+For ThreeTen Backport (http://www.threeten.org/threetenbp/):
+This is licensed under the BSD license, see above.
+
+==
+
+For Chart.js (http://www.chartjs.org/):
+This is licensed under the AL 2.0, see above.
+
+==
+
+For spin.js (http://spin.js.org/):
+This is licensed under the MIT license, see above.
+
+==
+
+For typeahead.js (http://twitter.github.io/typeahead.js/):
+This is licensed under the MIT license, see above.
+
+==
+
+For Wicket-Bootstrap (http://wb.agilecoders.de/):
+This is licensed under the AL 2.0, see above.
+
+==
+
+For X-editable (http://vitalets.github.io/x-editable/):
+This is licensed under the MIT license, see above.
+
+==
+
+For Source Sans Pro (https://github.com/adobe-fonts/source-sans-pro):
+This is lincesed under the SIL Open Font License, Version 1.1:
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/docker/console/NOTICE b/docker/console/NOTICE
new file mode 100644
index 0000000..b944552
--- /dev/null
+++ b/docker/console/NOTICE
@@ -0,0 +1,151 @@
+Apache Syncope
+Copyright 2012-2019 The Apache Software Foundation
+
+This product includes software developed by:
+The Apache Software Foundation (http://www.apache.org/).
+
+The following copyright notice(s) were affixed to portions of this code
+with which this file is now or was at one time distributed.
+
+==
+
+This product includes software developed by the Animate.css project.
+Copyright (c) 2016 Daniel Eden
+
+==
+
+This product includes software developed by the Bootbox.js project.
+Copyright (C) 2011-2015 by Nick Payne nick@kurai.co.uk
+
+==
+
+This product includes software developed by the Bootstrap project.
+Copyright (c) 2011-2016 Twitter, Inc.
+
+==
+
+This product includes software developed by the Modernizr project.
+Copyright (C) 2016
+
+==
+
+This product includes software developed by the Jackson project.
+
+==
+
+This product includes software developed by the Google Guava project.
+Copyright (c) 2016 The Guava Authors.
+
+==
+
+This product includes software developed by the Wicket - jQuery UI project.
+Copyright 2012-2013 Sebastien Briquet
+
+==
+
+This product includes software developed by the JAXB project.
+Copyright (c) 2013-2016 The JAXB project.
+
+==
+
+This product includes software developed by the google-diff-match-patch project.
+Copyright (c) 2006 Google Inc.
+
+==
+
+This product includes software developed by the Swagger project.
+Copyright 2016 SmartBear Software
+
+==
+
+This product includes software developed by the Ionicons project.
+Copyright (c) 2016 Drifty (http://drifty.com/)
+
+==
+
+This product includes software developed by the slimScroll project.
+Copyright (c) 2011 Piotr Rochala (http://rocha.la)
+
+==
+
+This product includs software developed by Oracle.
+Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+
+==
+
+This product includes software developed by the Bean Validation Project (http://beanvalidation.org).
+Copyright (c) Red Hat, Inc., Emmanuel Bernard
+
+==
+
+This product includes software developed by the JAX-RS project.
+Copyright (c) 2014, Oracle Corporation and/or its affiliates. All rights reserved.
+
+==
+
+This product includes software developed by the Joda Time project.
+Copyright (c) 2002-2016 Joda.org. All Rights Reserved.
+
+==
+
+This product includes the jQuery Core JavaScript Library.
+Copyright 2007, 2016 jQuery Foundation and other contributors.
+
+==
+
+This product includes software developed by the jquery.cookie project.
+Copyright 2014 Klaus Hartl
+
+==
+
+This product includes the jQuery UI JavaScript Library.
+Copyright 2007, 2015 jQuery Foundation and other contributors.
+
+==
+
+This product includes software developed by the jQuery++ project.
+Copyright (C) 2012 Bitovi
+
+==
+
+This product includes software developed by the jsPlumb project.
+Copyright (c) 2010 - 2014 jsPlumb, http://jsplumbtoolkit.com/
+
+==
+
+This product includes software developed by the Stax 2 Extension API Project.
+
+==
+
+This product includes software developed by the Woodstox Project.
+
+==
+
+This products includes software developed by the Simple Logging Facade for Java (SLF4J) project.
+Copyright (c) 2004-2016 QOS.ch.
+
+==
+
+This product includes software developed by SpringSource.
+Copyright (c) 2004-2016 SpringSource
+All rights reserved.
+
+==
+
+This product includes software developed by the spin.js project.
+Copyright (c) 2011-2015 Felix Gnass [fgnass at gmail dot com]
+
+==
+
+This product includes software developed by the Chart.js project.
+Copyright (c) 2018 Chart.js Contributors
+
+==
+
+This product includes software developed by the X-editable project.
+Copyright (c) 2012 Vitaliy Potapov
+
+==
+
+This product includes software developed by Adobe Systems Incorporated (http://www.adobe.com/).
+Copyright 2010, 2012, 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
diff --git a/docker/console/pom.xml b/docker/console/pom.xml
index 211e5af..8ecfb3e 100644
--- a/docker/console/pom.xml
+++ b/docker/console/pom.xml
@@ -31,6 +31,7 @@ under the License.
   <description>Apache Syncope Docker Console</description>
   <groupId>org.apache.syncope</groupId>
   <artifactId>syncope-docker-console</artifactId>
+  <packaging>war</packaging>
 
   <properties>
     <rootpom.basedir>${basedir}/../..</rootpom.basedir>
@@ -38,19 +39,44 @@ under the License.
   
   <dependencies>
     <dependency>
-      <groupId>org.apache.syncope</groupId>
-      <artifactId>syncope-deb-console</artifactId>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-undertow</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.syncope.client.idm</groupId>
+      <artifactId>syncope-client-idm-console</artifactId>
       <version>${project.version}</version>
-      <type>war</type>
-      <scope>test</scope>
     </dependency>
 
     <dependency>
-      <groupId>org.apache.syncope.fit</groupId>
-      <artifactId>syncope-fit-console-reference</artifactId>
+      <groupId>org.apache.syncope.ext.flowable</groupId>
+      <artifactId>syncope-ext-flowable-client-console</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.syncope.ext.camel</groupId>
+      <artifactId>syncope-ext-camel-client-console</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.syncope.ext.saml2sp</groupId>
+      <artifactId>syncope-ext-saml2sp-client-console</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.syncope.ext.oidcclient</groupId>
+      <artifactId>syncope-ext-oidcclient-client-console</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.syncope.ext.scimv2</groupId>
+      <artifactId>syncope-ext-scimv2-client-console</artifactId>
       <version>${project.version}</version>
-      <type>war</type>
-      <scope>test</scope>
     </dependency>
   </dependencies>
 
@@ -58,20 +84,39 @@ under the License.
     <plugins>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-antrun-plugin</artifactId>
-        <inherited>true</inherited>
+        <artifactId>maven-war-plugin</artifactId>
+        <inherited>false</inherited>
+        <configuration>
+          <webXml>${basedir}/../../fit/console-reference/src/main/webapp/WEB-INF/web.xml</webXml>
+          <webResources>
+            <resource>
+              <directory>${basedir}</directory>
+              <targetPath>META-INF</targetPath>
+              <includes>
+                <include>LICENSE</include>
+                <include>NOTICE</include>
+              </includes>
+            </resource>
+          </webResources>        
+          <outputDirectory>${project.build.outputDirectory}</outputDirectory>        
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-maven-plugin</artifactId>
+        <configuration>
+          <mainClass>org.apache.syncope.client.console.SyncopeConsoleApplication</mainClass>
+          <layout>ZIP</layout>
+        </configuration>
         <executions>
           <execution>
-            <id>setup</id>
-            <phase>process-resources</phase>
-            <configuration>
-              <target>
-                <copy file="${basedir}/../../deb/console/target/apache-syncope-console-${project.version}.deb" todir="${project.build.directory}/classes" overwrite="true" />
-              </target>
-            </configuration>
             <goals>
-              <goal>run</goal>
+              <goal>repackage</goal>
             </goals>
+            <configuration>
+              <outputDirectory>${project.build.outputDirectory}</outputDirectory>
+            </configuration>
           </execution>
         </executions>
       </plugin>
@@ -85,7 +130,7 @@ under the License.
             <image>
               <name>apache/syncope-console:%v</name>
               <build>
-                <dockerFileDir>${project.build.directory}/classes</dockerFileDir>
+                <dockerFileDir>${project.build.outputDirectory}</dockerFileDir>
               </build>
             </image>
           </images>
@@ -114,6 +159,14 @@ under the License.
         <directory>src/main/resources</directory>
         <filtering>true</filtering>
       </resource>
+      
+      <resource>
+        <directory>${project.basedir}/../../client/idrepo/console/src/main/resources</directory>
+        <includes>
+          <include>application.properties</include>
+        </includes>
+        <filtering>true</filtering>
+      </resource>
     </resources>
   </build>
 
diff --git a/docker/console/src/main/resources/Dockerfile b/docker/console/src/main/resources/Dockerfile
index 8875218..990959d 100644
--- a/docker/console/src/main/resources/Dockerfile
+++ b/docker/console/src/main/resources/Dockerfile
@@ -15,20 +15,25 @@
 # specific language governing permissions and limitations
 # under the License.
 
-FROM debian:stable-slim
+FROM adoptopenjdk/openjdk8-openj9:alpine-slim
 MAINTAINER dev@syncope.apache.org
 
 RUN set -x
 
-COPY *.deb /tmp/
+RUN mkdir /opt/syncope
+RUN mkdir /opt/syncope/bin
+RUN mkdir /opt/syncope/conf
+RUN mkdir /opt/syncope/lib
+RUN mkdir /opt/syncope/log
 
-COPY *.properties.template /etc/apache-syncope/
+COPY application.properties /opt/syncope/conf/
... 10920 lines suppressed ...


Mime
View raw message