From bee5dd259a4438d45ecd1bcc26dfba12875236d6 Mon Sep 17 00:00:00 2001
From: Thomas Lenz <thomas.lenz@egiz.gv.at>
Date: Tue, 26 Jun 2018 11:03:48 +0200
Subject: initial commit

---
 .../gv/egiz/eaaf/core/api/IDestroyableObject.java  |   16 +
 .../eaaf/core/api/IGarbageCollectorProcessing.java |   16 +
 .../eaaf/core/api/IPostStartupInitializable.java   |   21 +
 .../java/at/gv/egiz/eaaf/core/api/IRequest.java    |  234 ++++
 .../at/gv/egiz/eaaf/core/api/IRequestStorage.java  |   40 +
 .../at/gv/egiz/eaaf/core/api/IStatusMessager.java  |   49 +
 .../eaaf/core/api/data/EAAFConfigConstants.java    |    8 +
 .../gv/egiz/eaaf/core/api/data/EAAFConstants.java  |   42 +
 .../eaaf/core/api/data/ExceptionContainer.java     |   74 ++
 .../egiz/eaaf/core/api/data/ILoALevelMapper.java   |   22 +
 .../core/api/data/PVPAttributeDefinitions.java     |  251 ++++
 .../eaaf/core/api/data/XMLNamespaceConstants.java  |  474 ++++++++
 .../core/api/gui/IGUIBuilderConfiguration.java     |   54 +
 .../api/gui/IGUIBuilderConfigurationFactory.java   |   30 +
 .../gv/egiz/eaaf/core/api/gui/IGUIFormBuilder.java |   70 ++
 .../api/gui/ModifyableGuiBuilderConfiguration.java |   25 +
 .../core/api/idp/EAAFAuthProcessDataConstants.java |   21 +
 .../java/at/gv/egiz/eaaf/core/api/idp/IAction.java |   43 +
 .../egiz/eaaf/core/api/idp/IAttributeBuilder.java  |   32 +
 .../eaaf/core/api/idp/IAttributeGenerator.java     |   39 +
 .../at/gv/egiz/eaaf/core/api/idp/IAuthData.java    |  198 ++++
 .../core/api/idp/IAuthenticationDataBuilder.java   |   14 +
 .../gv/egiz/eaaf/core/api/idp/IConfiguration.java  |  108 ++
 .../at/gv/egiz/eaaf/core/api/idp/IModulInfo.java   |   75 ++
 .../eaaf/core/api/idp/IPVPAttributeBuilder.java    |    9 +
 .../egiz/eaaf/core/api/idp/ISPConfiguration.java   |  131 +++
 .../core/api/idp/auth/IAuthenticationManager.java  |   72 ++
 .../egiz/eaaf/core/api/idp/auth/ISSOManager.java   |   92 ++
 .../idp/auth/data/IAuthProcessDataContainer.java   |  144 +++
 .../eaaf/core/api/idp/auth/data/IIdentityLink.java |  155 +++
 .../eaaf/core/api/idp/auth/modules/AuthModule.java |   44 +
 .../core/api/idp/process/ExecutionContext.java     |   65 +
 .../idp/process/ExpressionEvaluationContext.java   |   25 +
 .../core/api/idp/process/ExpressionEvaluator.java  |   27 +
 .../eaaf/core/api/idp/process/ProcessEngine.java   |  114 ++
 .../api/idp/process/ProcessInstanceStoreDAO.java   |   47 +
 .../at/gv/egiz/eaaf/core/api/idp/process/Task.java |   28 +
 .../core/api/idp/slo/ISLOInformationContainer.java |   68 ++
 .../core/api/idp/slo/SLOInformationInterface.java  |   80 ++
 .../eaaf/core/api/logging/IRevisionLogger.java     |   38 +
 .../eaaf/core/api/logging/IStatisticLogger.java    |   20 +
 .../eaaf/core/api/storage/ITransactionStorage.java |  114 ++
 .../core/exceptions/AttributeBuilderException.java |   13 +
 .../core/exceptions/AttributePolicyException.java  |   20 +
 .../exceptions/AuthnRequestValidatorException.java |   49 +
 .../exceptions/EAAFAuthenticationException.java    |   21 +
 .../eaaf/core/exceptions/EAAFBuilderException.java |   20 +
 .../exceptions/EAAFConfigurationException.java     |   20 +
 .../egiz/eaaf/core/exceptions/EAAFException.java   |   45 +
 .../eaaf/core/exceptions/EAAFIDPException.java     |   17 +
 .../core/exceptions/EAAFIllegalStateException.java |   15 +
 .../eaaf/core/exceptions/EAAFParserException.java  |   20 +
 .../core/exceptions/EAAFProtocolException.java     |   26 +
 .../eaaf/core/exceptions/EAAFSSOException.java     |   17 +
 .../eaaf/core/exceptions/EAAFStorageException.java |   18 +
 .../eaaf/core/exceptions/GUIBuildException.java    |   26 +
 .../InvalidDateFormatAttributeException.java       |   15 +
 .../InvalidProtocolRequestException.java           |   23 +
 .../NoPassivAuthenticationException.java           |   18 +
 .../core/exceptions/ProcessExecutionException.java |   38 +
 .../exceptions/ProtocolNotActiveException.java     |   20 +
 .../gv/egiz/eaaf/core/exceptions/SLOException.java |   21 +
 .../core/exceptions/TaskExecutionException.java    |   55 +
 .../exceptions/UnavailableAttributeException.java  |   22 +
 .../egiz/eaaf/core/exceptions/XPathException.java  |   68 ++
 .../java/at/gv/egiz/eaaf/core/impl/data/Pair.java  |   25 +
 .../eaaf/core/impl/data/SLOInformationImpl.java    |  167 +++
 .../at/gv/egiz/eaaf/core/impl/data/Trible.java     |   31 +
 .../gui/AbstractGUIFormBuilderConfiguration.java   |   90 ++
 .../core/impl/gui/AbstractGUIFormBuilderImpl.java  |  192 +++
 .../core/impl/gui/velocity/VelocityLogAdapter.java |   81 ++
 .../core/impl/gui/velocity/VelocityProvider.java   |  121 ++
 .../eaaf/core/impl/idp/AuthenticationData.java     |  416 +++++++
 .../impl/idp/EAAFCoreSpringResourceProvider.java   |   30 +
 .../idp/auth/AbstractAuthenticationManager.java    |  341 ++++++
 .../eaaf/core/impl/idp/auth/RequestStorage.java    |  119 ++
 .../builder/AbstractAuthenticationDataBuilder.java |  467 ++++++++
 .../core/impl/idp/auth/builder/BPKBuilder.java     |  302 +++++
 .../impl/idp/auth/data/AuthProcessDataWrapper.java |  219 ++++
 .../eaaf/core/impl/idp/auth/data/IdentityLink.java |  312 +++++
 .../data/SimpleIdentityLinkAssertionParser.java    |  326 +++++
 .../idp/auth/modules/AbstractAuthServletTask.java  |  220 ++++
 .../impl/idp/auth/modules/ModuleRegistration.java  |  151 +++
 .../builder/attributes/BPKAttributeBuilder.java    |   55 +
 .../attributes/BirthdateAttributeBuilder.java      |   40 +
 .../builder/attributes/EIDIdentityLinkBuilder.java |   54 +
 .../EIDIssuingNationAttributeBuilder.java          |   35 +
 .../attributes/EIDSectorForIDAttributeBuilder.java |   36 +
 .../impl/idp/builder/attributes/EIDSourcePIN.java  |   39 +
 .../idp/builder/attributes/EIDSourcePINType.java   |   33 +
 .../EIDeIDASQAALevelAttributeBuilder.java          |   31 +
 .../attributes/GivenNameAttributeBuilder.java      |   26 +
 .../attributes/PVPVersionAttributeBuilder.java     |   26 +
 .../attributes/PrincipalNameAttributeBuilder.java  |   26 +
 .../impl/idp/conf/AbstractConfigurationImpl.java   |  185 +++
 .../core/impl/idp/conf/SPConfigurationImpl.java    |  163 +++
 .../AbstractAuthProtocolModulController.java       |  225 ++++
 .../impl/idp/controller/AbstractController.java    |  354 ++++++
 .../AbstractProcessEngineSignalController.java     |   97 ++
 .../controller/ProtocolFinalizationController.java |  178 +++
 .../impl/idp/controller/protocols/RequestImpl.java |  386 ++++++
 .../tasks/FinalizeAuthenticationTask.java          |   57 +
 .../tasks/RestartAuthProzessManagement.java        |   92 ++
 .../impl/idp/process/ExecutionContextImpl.java     |   81 ++
 .../process/ExpressionEvaluationContextImpl.java   |   46 +
 .../impl/idp/process/ProcessDefinitionParser.java  |  226 ++++
 .../process/ProcessDefinitionParserException.java  |   37 +
 .../core/impl/idp/process/ProcessEngineImpl.java   |  424 +++++++
 .../core/impl/idp/process/ProcessInstance.java     |  166 +++
 .../impl/idp/process/ProcessInstanceState.java     |   32 +
 .../impl/idp/process/dao/ProcessInstanceStore.java |   75 ++
 .../process/dao/ProcessInstanceStoreDAOImpl.java   |   73 ++
 .../eaaf/core/impl/idp/process/model/EndEvent.java |   44 +
 .../impl/idp/process/model/ProcessDefinition.java  |  160 +++
 .../core/impl/idp/process/model/ProcessNode.java   |   71 ++
 .../core/impl/idp/process/model/StartEvent.java    |   47 +
 .../eaaf/core/impl/idp/process/model/TaskInfo.java |   96 ++
 .../core/impl/idp/process/model/Transition.java    |  138 +++
 .../process/spring/SpringExpressionEvaluator.java  |   63 +
 .../springweb/AbstractAuthSourceServlet.java       |  118 ++
 .../impl/idp/process/springweb/AbstractTask.java   |  101 ++
 .../springweb/SpringWebExpressionEvaluator.java    |  145 +++
 .../idp/process/support/SecureRandomHolder.java    |   37 +
 .../core/impl/logging/DummyRevisionsLogger.java    |   52 +
 .../core/impl/logging/DummyStatisticLogger.java    |   43 +
 .../at/gv/egiz/eaaf/core/impl/utils/DOMUtils.java  | 1243 ++++++++++++++++++++
 .../egiz/eaaf/core/impl/utils/DataURLBuilder.java  |  113 ++
 .../core/impl/utils/EAAFDomEntityResolver.java     |  104 ++
 .../at/gv/egiz/eaaf/core/impl/utils/FileUtils.java |  142 +++
 .../at/gv/egiz/eaaf/core/impl/utils/HTTPUtils.java |  178 +++
 .../egiz/eaaf/core/impl/utils/KeyStoreUtils.java   |  175 +++
 .../egiz/eaaf/core/impl/utils/KeyValueUtils.java   |  319 +++++
 .../eaaf/core/impl/utils/NodeIteratorAdapter.java  |   89 ++
 .../egiz/eaaf/core/impl/utils/NodeListAdapter.java |   46 +
 .../at/gv/egiz/eaaf/core/impl/utils/Random.java    |  205 ++++
 .../gv/egiz/eaaf/core/impl/utils/ServletUtils.java |   69 ++
 .../gv/egiz/eaaf/core/impl/utils/StreamUtils.java  |  177 +++
 .../eaaf/core/impl/utils/TransactionIDUtils.java   |   85 ++
 .../gv/egiz/eaaf/core/impl/utils/XPathUtils.java   |  523 ++++++++
 139 files changed, 15327 insertions(+)
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IDestroyableObject.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IGarbageCollectorProcessing.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IPostStartupInitializable.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IRequest.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IRequestStorage.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IStatusMessager.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConfigConstants.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConstants.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/ExceptionContainer.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/ILoALevelMapper.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/PVPAttributeDefinitions.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/XMLNamespaceConstants.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/IGUIBuilderConfiguration.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/IGUIBuilderConfigurationFactory.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/IGUIFormBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/ModifyableGuiBuilderConfiguration.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/EAAFAuthProcessDataConstants.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAction.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAttributeBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAttributeGenerator.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAuthData.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAuthenticationDataBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IConfiguration.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IModulInfo.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IPVPAttributeBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/ISPConfiguration.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/IAuthenticationManager.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/ISSOManager.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/data/IAuthProcessDataContainer.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/data/IIdentityLink.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/modules/AuthModule.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ExecutionContext.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ExpressionEvaluationContext.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ExpressionEvaluator.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ProcessEngine.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ProcessInstanceStoreDAO.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/Task.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/slo/ISLOInformationContainer.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/slo/SLOInformationInterface.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/logging/IRevisionLogger.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/logging/IStatisticLogger.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/storage/ITransactionStorage.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/AttributeBuilderException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/AttributePolicyException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/AuthnRequestValidatorException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFAuthenticationException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFBuilderException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFConfigurationException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFIDPException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFIllegalStateException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFParserException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFProtocolException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFSSOException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFStorageException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/GUIBuildException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/InvalidDateFormatAttributeException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/InvalidProtocolRequestException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/NoPassivAuthenticationException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/ProcessExecutionException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/ProtocolNotActiveException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/SLOException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/TaskExecutionException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/UnavailableAttributeException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/XPathException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/Pair.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/SLOInformationImpl.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/Trible.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/AbstractGUIFormBuilderConfiguration.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/AbstractGUIFormBuilderImpl.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/velocity/VelocityLogAdapter.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/velocity/VelocityProvider.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/AuthenticationData.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/EAAFCoreSpringResourceProvider.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/RequestStorage.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BPKBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/IdentityLink.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/SimpleIdentityLinkAssertionParser.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/ModuleRegistration.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BPKAttributeBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BirthdateAttributeBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDIdentityLinkBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDIssuingNationAttributeBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDSectorForIDAttributeBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDSourcePIN.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDSourcePINType.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDeIDASQAALevelAttributeBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/GivenNameAttributeBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/PVPVersionAttributeBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/PrincipalNameAttributeBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/AbstractConfigurationImpl.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/SPConfigurationImpl.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractAuthProtocolModulController.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/FinalizeAuthenticationTask.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/RestartAuthProzessManagement.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExecutionContextImpl.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExpressionEvaluationContextImpl.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParserException.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstance.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstanceState.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStore.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDAOImpl.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/EndEvent.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessDefinition.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessNode.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/StartEvent.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/TaskInfo.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/Transition.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/spring/SpringExpressionEvaluator.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractAuthSourceServlet.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractTask.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/SpringWebExpressionEvaluator.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/logging/DummyRevisionsLogger.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/logging/DummyStatisticLogger.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DOMUtils.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataURLBuilder.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/EAAFDomEntityResolver.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HTTPUtils.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIDUtils.java
 create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/XPathUtils.java

(limited to 'eaaf_core/src/main/java/at/gv')

diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IDestroyableObject.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IDestroyableObject.java
new file mode 100644
index 00000000..52979cd2
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IDestroyableObject.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api;
+
+/**
+ * @author tlenz
+ *
+ */
+public interface IDestroyableObject {
+	/**
+	 * Manually deep destroy a Java object with all child objects like timers and threads 
+	 * 
+	 */
+	public void fullyDestroy();
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IGarbageCollectorProcessing.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IGarbageCollectorProcessing.java
new file mode 100644
index 00000000..7b153b2e
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IGarbageCollectorProcessing.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api;
+
+/**
+ * @author tlenz
+ *
+ */
+public interface IGarbageCollectorProcessing {
+
+	/**
+	 * This method gets executed by the MOA garbage collector at regular intervals.
+	 * 
+	 */
+	public void runGarbageCollector();
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IPostStartupInitializable.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IPostStartupInitializable.java
new file mode 100644
index 00000000..f2fae3af
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IPostStartupInitializable.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api;
+
+
+/**
+ * 
+ * @author tlenz
+ *
+ * Interface initialize a Object when the MOA-ID-Auth start-up process is fully completed
+ *
+ */
+public interface IPostStartupInitializable {
+
+	/**
+	 * This method is called once when MOA-ID-Auth start-up process is fully completed
+	 * 
+	 */
+	public void executeAfterStartup();
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IRequest.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IRequest.java
new file mode 100644
index 00000000..02070ee1
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IRequest.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ *******************************************************************************/
+/*******************************************************************************
+*
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api;
+
+import java.util.Map;
+
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException;
+
+public interface IRequest {
+		
+	/**
+	 * Indicates the module, which implements this authentication protocol.
+	 * The class, which is referenced, had to implement the 'IModulInfo' interface.
+	 * 
+	 * @return Full-qualified name of the class which implements this protocol
+	 */
+	public String requestedModule();
+	
+	/**
+	 * Indicates the protocol specific action, which should executed if the request is processed. 
+	 * The class, which is referenced, had to implement the 'IAction' interface.
+	 * 
+	 * @return Full-qualified name of the class which implements the action  
+	 */
+	public String requestedAction();
+	
+	/**
+	 * Unique identifier, which indicates the service provider. 
+	 * 
+	 * @return Unique identifier for the service provider
+	 */
+	public String getSPEntityId();
+	
+	/**
+	 * Indicates the passive flag in authentication requests.
+	 * If the passive flag is set, the identification and authentication process 
+	 * failed if no active SSO session is found. 
+	 * 
+	 * @return true, if the is passive flag is set in authentication request, otherwise false
+	 */
+	public boolean isPassiv();
+	
+	/**
+	 * Indicates the force authentication flag in authentication request
+	 * If this flag is set, a new identification and authentication process
+	 * is carried out in any case.
+	 * 
+	 * @return true, if the force authentication flag is set, otherwise false
+	 */
+	public boolean forceAuth();
+	
+	
+	/**
+	 * Returns a generic request-data object with is stored with a specific identifier 
+	 * 
+	 * @param key The specific identifier of the request-data object
+	 * @return The request-data object or null if no data is found with this key
+	 */
+	public Object getGenericData(String key);
+	
+	/**
+	 * Returns a generic request-data object with is stored with a specific identifier 
+	 * 
+	 * @param key The specific identifier of the request-data object
+	 * @param clazz The class type which is stored with this key
+	 * @return The request-data object or null if no data is found with this key
+	 */
+	public <T> T getGenericData(String key, final Class<T> clazz);
+	
+	/** 
+	 * Store a generic data-object into pending request with a specific identifier
+	 * 
+	 * @param key Identifier for this data-object
+	 * @param object Generic data-object which should be stored. This data-object had to be implement the 'java.io.Serializable' interface
+	 * @throws SessionDataStorageException Error message if the data-object can not stored to generic request-data storage
+	 */
+	public void setGenericDataToSession(String key, Object object) throws EAAFStorageException;
+
+	/** 
+	 * Store generic data-objects into pending request with specific identifiers
+	 * 
+	 * @param map Map with Identifiers and values
+	 * @throws SessionDataStorageException Error message if the data-object can not stored to generic request-data storage
+	 */
+	public void setGenericDataToSession(Map<String, Object> map) throws EAAFStorageException;
+	
+	
+	
+	/**
+	 * Get the internal dataStorage map
+	 * 
+	 * @return read-only map of data stored to this pending request
+	 */
+	public Map<String, Object> genericFullDataStorage();
+	
+	/**
+	 * Hold the identifier of this request object. 
+	 * This identifier can be used to load the request from request storage 
+	 * 
+	 * @return Request identifier
+	 */
+	public String getPendingRequestId();
+	
+
+	/**
+	 * Hold the identifier of the SSO-Session which is associated with this request
+	 * 
+	 * @return SSO session-identifier if a associated session exists, otherwise null
+	 */
+	public String getSSOSessionIdentifier();
+
+	/**
+	 * Set the in SSO session identifier, if an active SSO session exists
+	 * 
+	 * @param internalSSOSessionId
+	 */
+	public void setSSOSessionIdentifier(String internalSSOSessionId);
+	
+	/**
+	 * Holds a unique transaction identifier, which could be used for looging
+	 * This transaction identifier is unique for a single identification and authentication process
+	 * 
+	 * @return Unique transaction identifier. 
+	 */
+	public String getUniqueTransactionIdentifier();
+	
+	/**
+	 * Holds a unique session identifier, which could be used for logging 
+	 * This session identifier is unique for the full Single Sign-On session time
+	 * 
+	 * @return Unique session identifier
+	 */
+	public String getUniqueSessionIdentifier();
+	
+	
+	/**
+	 * Hold the identifier if the process instance, which is associated with this request 
+	 * 
+	 * @return ProcessInstanceID if this request is associated with a authentication process, otherwise null
+	 */
+	public String getProcessInstanceId();
+	
+	
+	/**
+	 * get the IDP URL PreFix, which was used for authentication request
+	 * 
+	 * @return IDP URL PreFix <String>. The URL prefix always ends without /
+	 */
+	public String getAuthURL();
+	public String getAuthURLWithOutSlash();
+	
+	/**
+	 * Indicates if this pending request needs authentication
+	 * 
+	 * @return true if this request needs authentication, otherwise false
+	 */
+	public boolean isNeedAuthentication();
+	
+	/**
+	 * Indicates, if this pending request needs Single Sign-On (SSO) functionality 
+	 * 
+	 * @return true if this request needs SSO, otherwise false
+	 */
+	public boolean needSingleSignOnFunctionality();
+	public void setNeedSingleSignOnFunctionality(boolean needSSO);
+	
+	
+	/**
+	 * Indicates, if this pending request needs an additional user consent 
+	 * 
+	 * @return true if this request needs additional user consent, otherwise false
+	 */
+	public boolean isNeedUserConsent();
+	public void setNeedUserConsent(boolean needConsent);
+	
+	/**
+	 * Indicates, if this pending request is already authenticated
+	 * 
+	 * @return true if this request is already authenticated, otherwise false
+	 */
+	public boolean isAuthenticated();
+	public void setAuthenticated(boolean isAuthenticated);
+	
+	/**
+	 * Get get Service-Provider configuration which is associated with this request.
+	 * 
+	 * @return Service-Provider configuration
+	 */
+	public ISPConfiguration getServiceProviderConfiguration();
+
+	
+	/**
+	 * Get get Service-Provider configuration which is associated with this request.
+	 * 
+	 * @return Service-Provider configuration as object
+	 */
+	public <T> T getServiceProviderConfiguration(final Class<T> decorator);
+	
+		
+	/**
+	 * Indicates, if this pending-request is aborted by the user
+	 * 
+	 * @return true, if it is aborted, otherwise false
+	 */
+	public boolean isAbortedByUser();
+
+	/**
+	 * Set the 'isAboredByUser' flag of this pending-request
+	 * 
+	 * @param b true, if the user has abort the authentication process, otherwise false
+	 */
+	public void setAbortedByUser(boolean isAborted);
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IRequestStorage.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IRequestStorage.java
new file mode 100644
index 00000000..ce526fa8
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IRequestStorage.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ *******************************************************************************/
+/*
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egiz.eaaf.core.api;
+
+
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+
+/**
+ * @author tlenz
+ *
+ */
+public interface IRequestStorage {
+
+	public IRequest getPendingRequest(String pendingReqID);
+	
+	public void storePendingRequest(IRequest pendingRequest) throws EAAFException;
+	
+	public void removePendingRequest(String requestID);
+	
+	public String changePendingRequestID(IRequest pendingRequest) throws EAAFException;
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IStatusMessager.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IStatusMessager.java
new file mode 100644
index 00000000..40d86352
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/IStatusMessager.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api;
+
+public interface IStatusMessager {
+
+	//internal error codes defined in EAAFCore
+	public static final String CODES_INTERNAL_ERROR_GENERIC = "internal.00";	
+	public static final String CODES_INTERNAL_ERROR_AUTH_NOSPCONFIG = "auth.00";
+	public static final String CODES_INTERNAL_ERROR_AUTH_NOPENDIGREQID = "auth.26";
+	public static final String CODES_INTERNAL_ERROR_AUTH_TIMEOUT = "auth.28";
+	public static final String CODES_INTERNAL_ERROR_AUTH_USERSTOP = "auth.21";
+	public static final String CODES_INTERNAL_ERROR_AUTH_REQUEST_INVALID = "auth.35";
+	
+	public static final String CODES_INTERNAL_ILLEGAL_STATE = "process.03";
+	
+	//external error codes defined in EAAFCore
+	public static final String CODES_EXTERNAL_ERROR_GENERIC = "9199";
+	public static final String CODES_EXTERNAL_ERROR_PROCESSENGINE = "1100";
+	
+	
+	/**
+	   * Get the message corresponding to a given message ID.
+	   *
+	   * @param messageId The ID of the message.
+	   * @param parameters The parameters to fill in into the message arguments.
+	   * @return The formatted message. 
+	   */
+	public String getMessage(String messageId, Object[] parameters);
+	
+	
+	/**
+	 * Get external errorCode from from Exception 
+	 * 
+	 * @param throwable
+	 * @return
+	 */
+	public String getResponseErrorCode(Throwable throwable);
+	
+	
+	/**
+	 * Map internal to external errorCode
+	 * 
+	 * @param intErrorCode
+	 * @return
+	 */
+	public String mapInternalErrorToExternalError(String intErrorCode);
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConfigConstants.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConfigConstants.java
new file mode 100644
index 00000000..4f35a681
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConfigConstants.java
@@ -0,0 +1,8 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.data;
+
+public class EAAFConfigConstants {
+
+	public static final String SERVICE_UNIQUEIDENTIFIER = "uniqueID";   	//publicURLPrefix
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConstants.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConstants.java
new file mode 100644
index 00000000..c9d1263a
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConstants.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.data;
+
+
+public class EAAFConstants {
+
+	public static final String CONTENTTYPE_HTML_UTF8 = "text/html; charset=UTF-8";
+	
+	//http request parameters for process management
+	public static final String PARAM_HTTP_TARGET_PENDINGREQUESTID = "pendingid";	
+	public static final String PARAM_HTTP_ERROR_CODE = "errorid";
+	 
+	
+	public static final String EIDAS_QAA_PREFIX = "http://eidas.europa.eu/LoA/";
+	public static final String EIDAS_QAA_LOW = EIDAS_QAA_PREFIX + "low";
+	public static final String EIDAS_QAA_SUBSTANTIAL = EIDAS_QAA_PREFIX + "substantial";
+	public static final String EIDAS_QAA_HIGH = EIDAS_QAA_PREFIX + "high";
+	
+	
+	//Austrian specific prefixes for pseudonyms of users 
+	public static final String URN_PREFIX = "urn:publicid:gv.at";
+	public static final String URN_PREFIX_BASEID = URN_PREFIX + ":baseid";
+	public static final String URN_PREFIX_CDID = URN_PREFIX + ":cdid+";	  
+	public static final String URN_PREFIX_BPK = URN_PREFIX_CDID + "bpk";		  
+	public static final String URN_PREFIX_WBPK = URN_PREFIX + ":wbpk+";
+	public static final String URN_PREFIX_EIDAS = URN_PREFIX + ":eidasid+";	
+		
+	//Authentication process data_constants
+	public static final String UNIQUESESSIONIDENTIFIER  = "eaaf_uniqueSessionIdentifier";
+	public static final String AUTH_DATA_CREATED 	    = "eaaf_authdata_created";
+	
+	
+	public static final String PROCESS_ENGINE_PREFIX = "PARAMS_";
+	public static final String PROCESS_ENGINE_PENDINGREQUESTID = PROCESS_ENGINE_PREFIX + PARAM_HTTP_TARGET_PENDINGREQUESTID;
+	public static final String PROCESS_ENGINE_SERVICE_PROVIDER_ENTITYID = PROCESS_ENGINE_PREFIX + "uniqueSPId";
+	public static final String PROCESS_ENGINE_SSL_CLIENT_CERTIFICATE = PROCESS_ENGINE_PREFIX + "holderofkey_cert";
+
+	public static final int ALLOWED_TIME_JITTER = 5; //minutes
+	public static final String COUNTRYCODE_AUSTRIA = "AT";
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/ExceptionContainer.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/ExceptionContainer.java
new file mode 100644
index 00000000..1b16d4c2
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/ExceptionContainer.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.data;
+
+import java.io.Serializable;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+
+/**
+ * @author tlenz
+ *
+ */
+public class ExceptionContainer implements Serializable {
+
+	private static final long serialVersionUID = 5355860753609684995L;
+	private Throwable exceptionThrown = null;
+	private IRequest pendingReq = null;
+	
+	
+	/**
+	 * 
+	 */
+	public ExceptionContainer(IRequest pendingReq, Throwable exception) {
+		this.pendingReq = pendingReq;					
+		this.exceptionThrown = exception;
+		
+	}
+	
+	/**
+	 * @return the exceptionThrown
+	 */
+	public Throwable getExceptionThrown() {
+		return this.exceptionThrown;
+	}
+	
+	public IRequest getPendingRequest() {
+		return this.pendingReq;
+		
+	}
+	
+	/**
+	 * @return the uniqueSessionID
+	 */
+	public String getUniqueSessionID() {
+		if (this.pendingReq != null)
+			return this.pendingReq.getUniqueSessionIdentifier();
+		else
+			return null;
+	}
+	/**
+	 * @return the uniqueTransactionID
+	 */
+	public String getUniqueTransactionID() {
+		if (this.pendingReq != null)
+			return this.pendingReq.getUniqueTransactionIdentifier();
+		else
+			return null;
+	}
+
+	/**
+	 * @return the uniqueServiceProviderId
+	 */
+	public String getUniqueServiceProviderId() {
+		if (this.pendingReq != null && 
+				this.pendingReq.getServiceProviderConfiguration() != null)
+			return this.pendingReq.getServiceProviderConfiguration().getUniqueIdentifier();
+		else
+			return null;
+	}
+	
+	
+	
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/ILoALevelMapper.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/ILoALevelMapper.java
new file mode 100644
index 00000000..d4f49916
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/ILoALevelMapper.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.data;
+
+public interface ILoALevelMapper {
+
+	/**
+	 * Map an arbitrary QAA level to eIDAS LoA
+	 * 
+	 * @param qaa, but not null
+	 * @return An eIDAS LoA if there is a mapping, otherwise null
+	 */
+	public String mapToeIDASLoA(String qaa);
+	
+	/**
+	 * Map an arbitrary QAA level to PVP SecClass
+	 * 
+	 * @param qaa, but not null
+	 * @return An PVP SecClass if there is a mapping, otherwise null
+	 */
+	public String mapToSecClass(String qaa);
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/PVPAttributeDefinitions.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/PVPAttributeDefinitions.java
new file mode 100644
index 00000000..9a439072
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/PVPAttributeDefinitions.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.data;
+
+public interface PVPAttributeDefinitions {
+
+	public static final String URN_OID_PREFIX = "urn:oid:";
+	
+	public static final String PVP_VERSION_OID = "1.2.40.0.10.2.1.1.261.10";
+	public static final String PVP_VERSION_NAME = URN_OID_PREFIX + PVP_VERSION_OID;
+	public static final String PVP_VERSION_FRIENDLY_NAME = "PVP-VERSION";
+	public static final String PVP_VERSION_2_1 = "2.1";
+
+	
+	public static final String SECCLASS_OID = "1.2.40.0.10.2.1.1.261.110";
+	public static final String SECCLASS_FRIENDLY_NAME = "SECCLASS";
+	public static final String SECCLASS_NAME = URN_OID_PREFIX + SECCLASS_OID;
+	public static final int SECCLASS_MAX_LENGTH = 128;
+	
+	public static final String PRINCIPAL_NAME_OID = "1.2.40.0.10.2.1.1.261.20";
+	public static final String PRINCIPAL_NAME_NAME = URN_OID_PREFIX + PRINCIPAL_NAME_OID;
+	public static final String PRINCIPAL_NAME_FRIENDLY_NAME = "PRINCIPAL-NAME";
+	public static final int PRINCIPAL_NAME_MAX_LENGTH = 128;
+	
+	public static final String GIVEN_NAME_OID = "2.5.4.42";
+	public static final String GIVEN_NAME_NAME = URN_OID_PREFIX + GIVEN_NAME_OID;
+	public static final String GIVEN_NAME_FRIENDLY_NAME = "GIVEN-NAME";
+	public static final int GIVEN_NAME_MAX_LENGTH = 128;
+	
+	public static final String BIRTHDATE_OID = "1.2.40.0.10.2.1.1.55";
+	public static final String BIRTHDATE_NAME = URN_OID_PREFIX + BIRTHDATE_OID;
+	public static final String BIRTHDATE_FRIENDLY_NAME = "BIRTHDATE";
+	public static final String BIRTHDATE_FORMAT_PATTERN = "yyyy-MM-dd";
+	
+	public static final String USERID_OID = "0.9.2342.19200300.100.1.1";
+	public static final String USERID_NAME = URN_OID_PREFIX + USERID_OID;
+	public static final String USERID_FRIENDLY_NAME = "USERID";
+	public static final int USERID_MAX_LENGTH = 128;
+	
+	public static final String GID_OID = "1.2.40.0.10.2.1.1.1";
+	public static final String GID_NAME = URN_OID_PREFIX + GID_OID;
+	public static final String GID_FRIENDLY_NAME = "GID";
+	public static final int GID_MAX_LENGTH = 128;
+	
+	public static final String BPK_OID = "1.2.40.0.10.2.1.1.149";
+	public static final String BPK_NAME = URN_OID_PREFIX + BPK_OID;
+	public static final String BPK_FRIENDLY_NAME = "BPK";
+	public static final int BPK_MAX_LENGTH = 1024;
+	
+	public static final String ENC_BPK_LIST_OID = "1.2.40.0.10.2.1.1.261.22";
+	public static final String ENC_BPK_LIST_NAME = URN_OID_PREFIX+ENC_BPK_LIST_OID;
+	public static final String ENC_BPK_LIST_FRIENDLY_NAME = "ENC-BPK-LIST";
+	public static final int ENC_BPK_LIST_MAX_LENGTH = 32767;
+	
+	public static final String MAIL_OID = "0.9.2342.19200300.100.1.3";
+	public static final String MAIL_NAME = URN_OID_PREFIX + MAIL_OID;
+	public static final String MAIL_FRIENDLY_NAME = "MAIL";
+	public static final int MAIL_MAX_LENGTH = 128;
+	
+	public static final String TEL_OID = "2.5.4.20";
+	public static final String TEL_NAME = URN_OID_PREFIX + TEL_OID;
+	public static final String TEL_FRIENDLY_NAME = "TEL";
+	public static final int TEL_MAX_LENGTH = 32;
+	
+	public static final String PARTICIPANT_ID_OID = "1.2.40.0.10.2.1.1.71";
+	public static final String PARTICIPANT_ID_NAME = URN_OID_PREFIX + PARTICIPANT_ID_OID;
+	public static final String PARTICIPANT_ID_FRIENDLY_NAME = "PARTICIPANT-ID";
+	public static final int PARTICIPANT_MAX_LENGTH = 39;
+	
+	public static final String PARTICIPANT_OKZ_OID = "1.2.40.0.10.2.1.1.261.24";
+	public static final String PARTICIPANT_OKZ_NAME = URN_OID_PREFIX + PARTICIPANT_OKZ_OID;
+	public static final String PARTICIPANT_OKZ_FRIENDLY_NAME = "PARTICIPANT-OKZ";
+	public static final int PARTICIPANT_OKZ_MAX_LENGTH = 32;
+	
+	public static final String OU_OKZ_OID = "1.2.40.0.10.2.1.1.153";
+	public static final String OU_OKZ_NAME =  URN_OID_PREFIX + OU_OKZ_OID;
+	public static final int OU_OKZ_MAX_LENGTH = 32;
+	
+	public static final String OU_GV_OU_ID_OID = "1.2.40.0.10.2.1.1.3";
+	public static final String OU_GV_OU_ID_NAME = URN_OID_PREFIX + OU_GV_OU_ID_OID;
+	public static final String OU_GV_OU_ID_FRIENDLY_NAME = "OU-GV-OU-ID";
+	public static final int OU_GV_OU_ID_MAX_LENGTH = 39;
+	
+	public static final String OU_OID = "2.5.4.11";
+	public static final String OU_NAME = URN_OID_PREFIX + OU_OID;
+	public static final String OU_FRIENDLY_NAME = "OU";
+	public static final int OU_MAX_LENGTH = 64;
+	
+	public static final String FUNCTION_OID = "1.2.40.0.10.2.1.1.33";
+	public static final String FUNCTION_NAME = URN_OID_PREFIX + FUNCTION_OID;
+	public static final String FUNCTION_FRIENDLY_NAME = "FUNCTION";
+	public static final int FUNCTION_MAX_LENGTH = 32;
+	
+	public static final String ROLES_OID = "1.2.40.0.10.2.1.1.261.30";
+	public static final String ROLES_NAME = URN_OID_PREFIX + ROLES_OID;
+	public static final String ROLES_FRIENDLY_NAME = "ROLES";
+	public static final int ROLES_MAX_LENGTH = 32767;
+	
+	@Deprecated public static final String EID_CITIZEN_QAA_LEVEL_OID = "1.2.40.0.10.2.1.1.261.94";	
+	@Deprecated public static final String EID_CITIZEN_QAA_LEVEL_NAME = URN_OID_PREFIX + EID_CITIZEN_QAA_LEVEL_OID;
+	@Deprecated public static final String EID_CITIZEN_QAA_LEVEL_FRIENDLY_NAME = "EID-CITIZEN-QAA-LEVEL";
+	
+	public static final String EID_CITIZEN_EIDAS_QAA_LEVEL_OID = "1.2.40.0.10.2.1.1.261.108";	
+	public static final String EID_CITIZEN_EIDAS_QAA_LEVEL_NAME = URN_OID_PREFIX + EID_CITIZEN_EIDAS_QAA_LEVEL_OID;
+	public static final String EID_CITIZEN_EIDAS_QAA_LEVEL_FRIENDLY_NAME = "EID-CITIZEN-QAA-EIDAS-LEVEL";
+	
+	public static final String EID_ISSUING_NATION_OID = "1.2.40.0.10.2.1.1.261.32";
+	public static final String EID_ISSUING_NATION_NAME = URN_OID_PREFIX + EID_ISSUING_NATION_OID;
+	public static final String EID_ISSUING_NATION_FRIENDLY_NAME = "EID-ISSUING-NATION";
+	public static final int EID_ISSUING_NATION_MAX_LENGTH = 2;
+	
+	public static final String EID_SECTOR_FOR_IDENTIFIER_OID = "1.2.40.0.10.2.1.1.261.34";
+	public static final String EID_SECTOR_FOR_IDENTIFIER_NAME = URN_OID_PREFIX + EID_SECTOR_FOR_IDENTIFIER_OID;
+	public static final String EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME = "EID-SECTOR-FOR-IDENTIFIER";
+	public static final int EID_SECTOR_FOR_IDENTIFIER_MAX_LENGTH = 255;
+	
+	public static final String EID_SOURCE_PIN_OID = "1.2.40.0.10.2.1.1.261.36";
+	public static final String EID_SOURCE_PIN_NAME = URN_OID_PREFIX + EID_SOURCE_PIN_OID;
+	public static final String EID_SOURCE_PIN_FRIENDLY_NAME = "EID-SOURCE-PIN";
+	public static final int EID_SOURCE_PIN_MAX_LENGTH = 128;
+	
+	public static final String EID_SOURCE_PIN_TYPE_OID = "1.2.40.0.10.2.1.1.261.104";
+	public static final String EID_SOURCE_PIN_TYPE_NAME = URN_OID_PREFIX + EID_SOURCE_PIN_TYPE_OID;
+	public static final String EID_SOURCE_PIN_TYPE_FRIENDLY_NAME = "EID-SOURCE-PIN-TYPE";
+	public static final int EID_SOURCE_PIN_TYPE_MAX_LENGTH = 128;
+	
+	public static final String EID_IDENTITY_LINK_OID = "1.2.40.0.10.2.1.1.261.38";
+	public static final String EID_IDENTITY_LINK_NAME = URN_OID_PREFIX + EID_IDENTITY_LINK_OID;
+	public static final String EID_IDENTITY_LINK_FRIENDLY_NAME = "EID-IDENTITY-LINK";
+	public static final int EID_IDENTITY_LINK_MAX_LENGTH = 32767;
+	
+	public static final String EID_AUTH_BLOCK_OID = "1.2.40.0.10.2.1.1.261.62";
+	public static final String EID_AUTH_BLOCK_NAME = URN_OID_PREFIX + EID_AUTH_BLOCK_OID;
+	public static final String EID_AUTH_BLOCK_FRIENDLY_NAME = "EID-AUTH-BLOCK";
+	public static final int EID_AUTH_BLOCK_MAX_LENGTH = 32767;
+	
+	public static final String EID_CCS_URL_OID = "1.2.40.0.10.2.1.1.261.64";
+	public static final String EID_CCS_URL_NAME = URN_OID_PREFIX + EID_CCS_URL_OID;
+	public static final String EID_CCS_URL_FRIENDLY_NAME = "EID-CCS-URL";
+	public static final int EID_CCS_URL_MAX_LENGTH = 1024;
+	
+	public static final String EID_SIGNER_CERTIFICATE_OID = "1.2.40.0.10.2.1.1.261.66";
+	public static final String EID_SIGNER_CERTIFICATE_NAME = URN_OID_PREFIX + EID_SIGNER_CERTIFICATE_OID;
+	public static final String EID_SIGNER_CERTIFICATE_FRIENDLY_NAME = "EID-SIGNER-CERTIFICATE";
+	public static final int EID_SIGNER_CERTIFICATE_MAX_LENGTH = 32767;
+	
+	public static final String EID_STORK_TOKEN_OID = "1.2.40.0.10.2.1.1.261.96";
+	public static final String EID_STORK_TOKEN_NAME = URN_OID_PREFIX + EID_STORK_TOKEN_OID;
+	public static final String EID_STORK_TOKEN_FRIENDLY_NAME = "EID-STORK-TOKEN";
+	public static final int EID_STORK_TOKEN_MAX_LENGTH = 32767;
+	
+	public static final String MANDATE_TYPE_OID = "1.2.40.0.10.2.1.1.261.68";
+	public static final String MANDATE_TYPE_NAME = URN_OID_PREFIX + MANDATE_TYPE_OID;
+	public static final String MANDATE_TYPE_FRIENDLY_NAME = "MANDATE-TYPE";
+	public static final int MANDATE_TYPE_MAX_LENGTH = 256;
+	
+	public static final String MANDATE_TYPE_OID_OID = "1.2.40.0.10.2.1.1.261.106";
+	public static final String MANDATE_TYPE_OID_NAME = URN_OID_PREFIX + MANDATE_TYPE_OID_OID;
+	public static final String MANDATE_TYPE_OID_FRIENDLY_NAME = "MANDATE-TYPE-OID";
+	public static final int MANDATE_TYPE_OID_MAX_LENGTH = 256;
+	
+	public static final String MANDATE_NAT_PER_SOURCE_PIN_OID = "1.2.40.0.10.2.1.1.261.70";
+	public static final String MANDATE_NAT_PER_SOURCE_PIN_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_SOURCE_PIN_OID;
+	public static final String MANDATE_NAT_PER_SOURCE_PIN_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-SOURCE-PIN";
+	public static final int MANDATE_NAT_PER_SOURCE_PIN_MAX_LENGTH = 128;
+	
+	public static final String MANDATE_LEG_PER_SOURCE_PIN_OID = "1.2.40.0.10.2.1.1.261.100";
+	public static final String MANDATE_LEG_PER_SOURCE_PIN_NAME = URN_OID_PREFIX + MANDATE_LEG_PER_SOURCE_PIN_OID;
+	public static final String MANDATE_LEG_PER_SOURCE_PIN_FRIENDLY_NAME = "MANDATOR-LEGAL-PERSON-SOURCE-PIN";
+	public static final int MANDATE_LEG_PER_SOURCE_PIN_MAX_LENGTH = 128;
+	
+	public static final String MANDATE_NAT_PER_SOURCE_PIN_TYPE_OID = "1.2.40.0.10.2.1.1.261.102";
+	public static final String MANDATE_NAT_PER_SOURCE_PIN_TYPE_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_SOURCE_PIN_TYPE_OID;
+	public static final String MANDATE_NAT_PER_SOURCE_PIN_TYPE_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-SOURCE-PIN-TYPE";
+	public static final int MANDATE_NAT_PER_SOURCE_PIN_TYPE_MAX_LENGTH = 128;
+	
+	public static final String MANDATE_LEG_PER_SOURCE_PIN_TYPE_OID = "1.2.40.0.10.2.1.1.261.76";
+	public static final String MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME = URN_OID_PREFIX + MANDATE_LEG_PER_SOURCE_PIN_TYPE_OID;
+	public static final String MANDATE_LEG_PER_SOURCE_PIN_TYPE_FRIENDLY_NAME = "MANDATOR-LEGAL-PERSON-SOURCE-PIN-TYPE";
+	public static final int MANDATE_LEG_PER_SOURCE_PIN_TYPE_MAX_LENGTH = 128;
+	
+	public static final String MANDATE_NAT_PER_BPK_OID = "1.2.40.0.10.2.1.1.261.98";
+	public static final String MANDATE_NAT_PER_BPK_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_BPK_OID;
+	public static final String MANDATE_NAT_PER_BPK_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-BPK";
+	public static final int MANDATE_NAT_PER_BPK_MAX_LENGTH = 1024;
+	
+	public static final String MANDATE_NAT_PER_ENC_BPK_LIST_OID = "1.2.40.0.10.2.1.1.261.72";
+	public static final String MANDATE_NAT_PER_ENC_BPK_LIST_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_ENC_BPK_LIST_OID;
+	public static final String MANDATE_NAT_PER_ENC_BPK_LIST_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-ENC-BPK-LIST";
+	public static final int MANDATE_NAT_PER_ENC_BPK_LIST_MAX_LENGTH = 32767;
+	
+	public static final String MANDATE_NAT_PER_GIVEN_NAME_OID = "1.2.40.0.10.2.1.1.261.78";
+	public static final String MANDATE_NAT_PER_GIVEN_NAME_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_GIVEN_NAME_OID;
+	public static final String MANDATE_NAT_PER_GIVEN_NAME_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-GIVEN-NAME";
+	public static final int MANDATE_NAT_PER_GIVEN_NAME_MAX_LENGTH = 128;
+	
+	public static final String MANDATE_NAT_PER_FAMILY_NAME_OID = "1.2.40.0.10.2.1.1.261.80";
+	public static final String MANDATE_NAT_PER_FAMILY_NAME_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_FAMILY_NAME_OID;
+	public static final String MANDATE_NAT_PER_FAMILY_NAME_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-FAMILY-NAME";
+	public static final int MANDATE_NAT_PER_FAMILY_NAME_MAX_LENGTH = 128;
+	
+	public static final String MANDATE_NAT_PER_BIRTHDATE_OID = "1.2.40.0.10.2.1.1.261.82";
+	public static final String MANDATE_NAT_PER_BIRTHDATE_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_BIRTHDATE_OID;
+	public static final String MANDATE_NAT_PER_BIRTHDATE_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-BIRTHDATE";
+	public static final String MANDATE_NAT_PER_BIRTHDATE_FORMAT_PATTERN = BIRTHDATE_FORMAT_PATTERN;
+	
+	public static final String MANDATE_LEG_PER_FULL_NAME_OID = "1.2.40.0.10.2.1.1.261.84";
+	public static final String MANDATE_LEG_PER_FULL_NAME_NAME = URN_OID_PREFIX + MANDATE_LEG_PER_FULL_NAME_OID;
+	public static final String MANDATE_LEG_PER_FULL_NAME_FRIENDLY_NAME = "MANDATOR-LEGAL-PERSON-FULL-NAME";
+	public static final int MANDATE_LEG_PER_FULL_NAME_MAX_LENGTH = 256;
+	
+	public static final String MANDATE_PROF_REP_OID_OID = "1.2.40.0.10.2.1.1.261.86";
+	public static final String MANDATE_PROF_REP_OID_NAME = URN_OID_PREFIX + MANDATE_PROF_REP_OID_OID;
+	public static final String MANDATE_PROF_REP_OID_FRIENDLY_NAME = "MANDATE-PROF-REP-OID";
+	public static final int MANDATE_PROF_REP_OID_MAX_LENGTH = 256;
+	
+	public static final String MANDATE_PROF_REP_DESC_OID = "1.2.40.0.10.2.1.1.261.88";
+	public static final String MANDATE_PROF_REP_DESC_NAME = URN_OID_PREFIX + MANDATE_PROF_REP_DESC_OID;
+	public static final String MANDATE_PROF_REP_DESC_FRIENDLY_NAME = "MANDATE-PROF-REP-DESCRIPTION";
+	public static final int MANDATE_PROF_REP_DESC_MAX_LENGTH = 1024;
+	
+	public static final String MANDATE_REFERENCE_VALUE_OID = "1.2.40.0.10.2.1.1.261.90";
+	public static final String MANDATE_REFERENCE_VALUE_NAME = URN_OID_PREFIX + MANDATE_REFERENCE_VALUE_OID;
+	public static final String MANDATE_REFERENCE_VALUE_FRIENDLY_NAME = "MANDATE-REFERENCE-VALUE";
+	public static final int MANDATE_REFERENCE_VALUE_MAX_LENGTH = 100;
+	
+	public static final String MANDATE_FULL_MANDATE_OID = "1.2.40.0.10.2.1.1.261.92";
+	public static final String MANDATE_FULL_MANDATE_NAME = URN_OID_PREFIX + MANDATE_FULL_MANDATE_OID;
+	public static final String MANDATE_FULL_MANDATE_FRIENDLY_NAME = "MANDATE-FULL-MANDATE";
+	public static final int MANDATE_FULL_MANDATE_MAX_LENGTH = 32767;
+	
+	public static final String INVOICE_RECPT_ID_OID = "1.2.40.0.10.2.1.1.261.40";
+	public static final String INVOICE_RECPT_ID_NAME = URN_OID_PREFIX + INVOICE_RECPT_ID_OID;
+	public static final String INVOICE_RECPT_ID_FRIENDLY_NAME = "INVOICE-RECPT-ID";
+	public static final int INVOICE_RECPT_ID_MAX_LENGTH = 64;
+	
+	public static final String COST_CENTER_ID_OID = "1.2.40.0.10.2.1.1.261.50";
+	public static final String COST_CENTER_ID_NAME = URN_OID_PREFIX + COST_CENTER_ID_OID;
+	public static final String COST_CENTER_ID_FRIENDLY_NAME = "COST-CENTER-ID";
+	public static final int COST_CENTER_ID_MAX_LENGTH = 32767;
+	
+	public static final String CHARGE_CODE_OID = "1.2.40.0.10.2.1.1.261.60";
+	public static final String CHARGE_CODE_NAME = URN_OID_PREFIX + CHARGE_CODE_OID;
+	public static final String CHARGE_CODE_FRIENDLY_NAME = "CHARGE-CODE";
+	public static final int CHARGE_CODE_MAX_LENGTH = 32767;
+	
+	public static final String PVP_HOLDEROFKEY_OID = "1.2.40.0.10.2.1.1.261.xx.xx";
+	public static final String PVP_HOLDEROFKEY_NAME = URN_OID_PREFIX + PVP_HOLDEROFKEY_OID;
+	public static final String PVP_HOLDEROFKEY_FRIENDLY_NAME = "HOLDER-OF-KEY-CERTIFICATE";
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/XMLNamespaceConstants.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/XMLNamespaceConstants.java
new file mode 100644
index 00000000..4ed321bd
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/XMLNamespaceConstants.java
@@ -0,0 +1,474 @@
+/*******************************************************************************
+ *******************************************************************************/
+
+
+package at.gv.egiz.eaaf.core.api.data;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Contains various constants used throughout the system.
+
+ */
+public interface XMLNamespaceConstants {
+  /** Root location of the schema files. */
+  public static final String SCHEMA_ROOT = "/schemas/";
+
+  /** URI of the Widerrufregister XML namespace. */
+  public static final String WRR_NS_URI =
+    "http://reference.e-government.gv.at/namespace/moavv/20041223";
+
+  /** Prefix used for the Widerrufregister XML namespace */
+  public static final String WRR_PREFIX = "wrr";
+
+  /** URI of the StandardTextBlock XML namespace. */
+  public static final String STB_NS_URI =
+    "http://reference.e-government.gv.at/namespace/standardtextblock/20041105#";
+
+  /** Prefix used for the standard text block XML namespace */
+  public static final String STB_PREFIX = "stb";
+
+  /** URI of the MOA XML namespace. */
+  public static final String MOA_NS_URI =
+    "http://reference.e-government.gv.at/namespace/moa/20020822#";
+
+  /** Name of the mandates infobox */
+  public static final String INFOBOXIDENTIFIER_MANDATES = "Mandates";
+
+  /** Prefix used for the Mandate XML namespace */
+  public static final String MD_PREFIX = "md";
+
+  /** URI of the Mandate XML namespace. */
+  public static final String MD_NS_URI =
+    "http://reference.e-government.gv.at/namespace/mandates/20040701#";
+
+  /** Prefix used for the Mandate XML namespace */
+  public static final String MVV_PREFIX = "mvv";
+
+  /** URI of the Mandate XML namespace. */
+  public static final String MVV_NS_URI =
+    "http://reference.e-government.gv.at/namespace/moavv/app2mvv/20041125";
+
+  /** Prefix used for the MandateCheckProfile XML namespace */
+  public static final String MDP_PREFIX = "mdp";
+
+  /** URI of the Mandate XML namespace. */
+  public static final String MDP_NS_URI =
+    "http://reference.e-government.gv.at/namespace/mandateprofile/20041105#";
+
+  /** Prefix used for the MOA XML namespace */
+  public static final String MOA_PREFIX = "moa";
+
+  /** Local location of the MOA XML schema definition. */
+  public static final String MOA_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "MOA-SPSS-2.0.0.xsd";
+
+  /** URI of the MOA configuration XML namespace. */
+  public static final String MOA_CONFIG_NS_URI =
+    "http://reference.e-government.gv.at/namespace/moaconfig/20021122#";
+
+  /** URI of the MOA ID configuration XML namespace. */
+  public static final String MOA_ID_CONFIG_NS_URI =
+    "http://www.buergerkarte.at/namespaces/moaconfig#";
+
+  /** Prefix used for the MOA configuration XML namespace */
+  public static final String MOA_CONFIG_PREFIX = "conf";
+
+  /** Prefix used for the MOA configuration XML namespace */
+  public static final String MOA_ID_CONFIG_PREFIX = "confID";
+
+  /** Local location of the MOA configuration XML schema definition. */
+  public static final String MOA_CONFIG_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "MOA-SPSS-config-2.0.0.xsd";
+
+  /** Local location of the MOA ID configuration XML schema definition. */
+  public static final String MOA_ID_CONFIG_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "MOA-ID-Configuration-1.5.2.xsd";
+
+  /** URI of the Security Layer 1.0 namespace. */
+  public static final String SL10_NS_URI =
+    "http://www.buergerkarte.at/namespaces/securitylayer/20020225#";
+
+  /** Prefix used for the Security Layer 1.0 XML namespace */
+  public static final String SL10_PREFIX = "sl10";
+
+  /** Local location of the Security Layer 1.0 XML schema definition */
+  public static final String SL10_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "Core.20020225.xsd";
+
+  /** URI of the Security Layer 1.1 XML namespace */
+  public static final String SL11_NS_URI =
+    "http://www.buergerkarte.at/namespaces/securitylayer/20020831#";
+
+  /** Prefix used for the Security Layer 1.1 XML namespace */
+  public static final String SL11_PREFIX = "sl11";
+
+  /** Local location of the Security Layer 1.1 XML schema definition */
+  public static final String SL11_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "Core.20020831.xsd";
+  
+  /** URI of the Security Layer 1.2 XML namespace */
+  public static final String SL12_NS_URI =
+    "http://www.buergerkarte.at/namespaces/securitylayer/1.2#";
+
+  /** Prefix used for the Security Layer 1.2 XML namespace */
+  public static final String SL12_PREFIX = "sl";
+
+  /** Local location of the Security Layer 1.2 XML schema definition */
+  public static final String SL12_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "Core-1.2.xsd";
+  
+  /** URI of the ECDSA XML namespace */
+  public static final String ECDSA_NS_URI =
+    "http://www.w3.org/2001/04/xmldsig-more#";
+  
+  /** Prefix used for ECDSA namespace */
+  public static final String ECDSA_PREFIX = "ecdsa";
+
+  /** Local location of ECDSA XML schema definition */
+  public static final String ECDSA_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "ECDSAKeyValue.xsd";
+
+  /** URI of the PersonData XML namespace. */
+  public static final String PD_NS_URI =
+    "http://reference.e-government.gv.at/namespace/persondata/20020228#";
+
+  /** Prefix used for the PersonData XML namespace */
+  public static final String PD_PREFIX = "pr";
+
+//  /** Local location of the PersonData XML schema definition */
+//  public static final String PD_SCHEMA_LOCATION =
+//    SCHEMA_ROOT + "PersonData.xsd";
+  
+  /** Local location of the PersonData XML schema definition */
+  public static final String PD_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "PersonData_20_en_moaWID.xsd";
+
+  /** URI of the SAML namespace. */
+  public static final String SAML_NS_URI =
+    "urn:oasis:names:tc:SAML:1.0:assertion";
+
+  /** Prefix used for the SAML XML namespace */
+  public static final String SAML_PREFIX = "saml";
+
+  /** Local location of the SAML XML schema definition. */
+  public static final String SAML_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "cs-sstc-schema-assertion-01.xsd";
+
+  /** URI of the SAML request-response protocol namespace. */
+  public static final String SAMLP_NS_URI =
+    "urn:oasis:names:tc:SAML:1.0:protocol";
+
+  /** Prefix used for the SAML request-response protocol namespace */
+  public static final String SAMLP_PREFIX = "samlp";
+
+  /** Local location of the SAML request-response protocol schema definition. */
+  public static final String SAMLP_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "cs-sstc-schema-protocol-01.xsd";
+
+  /** URI of the XML namespace. */
+  public static final String XML_NS_URI =
+    "http://www.w3.org/XML/1998/namespace";
+
+  /** Prefix used for the XML namespace */
+  public static final String XML_PREFIX = "xml";
+
+  /** Local location of the XML schema definition. */
+  public static final String XML_SCHEMA_LOCATION = SCHEMA_ROOT + "xml.xsd";
+
+  /** URI of the XMLNS namespace */
+  public static final String XMLNS_NS_URI = "http://www.w3.org/2000/xmlns/";
+
+  /** Prefix used for the XSI namespace */
+  public static final String XSI_PREFIX = "xsi";
+
+  /** Local location of the XSI schema definition. */
+  public static final String XSI_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "XMLSchema-instance.xsd";
+
+  /** URI of the XSI XMLNS namespace */
+  public static final String XSI_NS_URI =
+    "http://www.w3.org/2001/XMLSchema-instance";
+
+  /** URI of the XSLT XML namespace */
+  public static final String XSLT_NS_URI =
+    "http://www.w3.org/1999/XSL/Transform";
+
+  /** Prefix used for the XSLT XML namespace */
+  public static final String XSLT_PREFIX = "xsl";
+
+  /** URI of the XMLDSig XML namespace. */
+  public static final String DSIG_NS_URI = "http://www.w3.org/2000/09/xmldsig#";
+
+  /** Prefix used for the XMLDSig XML namespace */
+  public static final String DSIG_PREFIX = "dsig";
+
+  /** Local location of the XMLDSig XML schema. */
+  public static final String DSIG_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "xmldsig-core-schema.xsd";
+
+  /** URI of the XMLDSig XPath Filter XML namespace. */
+  public static final String DSIG_FILTER2_NS_URI =
+    "http://www.w3.org/2002/06/xmldsig-filter2";
+
+  /** Prefix used for the XMLDSig XPath Filter XML namespace */
+  public static final String DSIG_FILTER2_PREFIX = "dsig-filter2";
+
+  /** Local location of the XMLDSig XPath Filter XML schema definition. */
+  public static final String DSIG_FILTER2_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "xmldsig-filter2.xsd";
+
+  /** URI of the Exclusive Canonicalization XML namespace */
+  public static final String DSIG_EC_NS_URI =
+    "http://www.w3.org/2001/10/xml-exc-c14n#";
+    
+  /** Prefix used for the Exclusive Canonicalization XML namespace */
+  public static final String DSIG_EC_PREFIX = "ec";
+
+  /** Local location of the Exclusive Canonicalizaion XML schema definition */
+  public static final String DSIG_EC_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "exclusive-canonicalization.xsd";
+
+	/** URI of the XMLLoginParameterResolver Configuration XML namespace */
+	public static final String XMLLPR_NS_URI="http://reference.e-government.gv.at/namespace/moa/20020822#/xmllpr20030814";
+
+	/** Local location of the XMLLoginParameterResolver Configuration XML schema definition */
+	public static final String XMLLPR_SCHEMA_LOCATION =
+		SCHEMA_ROOT + "MOAIdentities.xsd";
+	
+  /** Local location of the XAdES v1.1.1 schema definition */ 
+  public static final String XADES_1_1_1_SCHEMA_LOCATION =
+	SCHEMA_ROOT + "XAdES-1.1.1.xsd";
+
+  /** URI of the XAdES v1.1.1 namespace */
+  public static final String XADES_1_1_1_NS_URI = "http://uri.etsi.org/01903/v1.1.1#";
+  
+  public static final String XADES_1_1_1_NS_PREFIX = "xades111";
+  
+  /** Local location of the XAdES v1.2.2 schema definition */ 
+  public static final String XADES_1_2_2_SCHEMA_LOCATION =
+	SCHEMA_ROOT + "XAdES-1.2.2.xsd";
+
+  /** URI of the XAdES v1.2.2 namespace */
+  public static final String XADES_1_2_2_NS_URI = "http://uri.etsi.org/01903/v1.2.2#";
+  
+  public static final String XADES_1_2_2_NS_PREFIX = "xades122";
+
+  /** Local location of the XAdES v1.1.1 schema definition */ 
+  public static final String XADES_1_3_2_SCHEMA_LOCATION =
+	SCHEMA_ROOT + "XAdES-1.3.2.xsd";
+
+  /** URI of the XAdES v1.3.2 namespace */
+  public static final String XADES_1_3_2_NS_URI = "http://uri.etsi.org/01903/v1.3.2#";
+  
+  public static final String XADES_1_3_2_NS_PREFIX = "xades132";
+
+  /** Local location of the XAdES v1.4.1 schema definition */ 
+  public static final String XADES_1_4_1_SCHEMA_LOCATION =
+	SCHEMA_ROOT + "XAdES-1.4.1.xsd";
+
+  /** URI of the XAdES v1.4.1 namespace */
+  public static final String XADES_1_4_1_NS_URI = "http://uri.etsi.org/01903/v1.4.1#";
+  
+  public static final String XADES_1_4_1_NS_PREFIX = "xades141";
+  /** URI of the SAML 2.0 namespace. */
+  public static final String SAML2_NS_URI =
+    "urn:oasis:names:tc:SAML:2.0:assertion";
+
+  /** Prefix used for the SAML 2.0 XML namespace */
+  public static final String SAML2_PREFIX = "saml2";
+
+  /** Local location of the SAML 2.0 XML schema definition. */
+  public static final String SAML2_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "saml-schema-assertion-2.0.xsd";
+  
+  /** URI of the SAML 2.0 protocol namespace. */
+  public static final String SAML2P_NS_URI =
+    "urn:oasis:names:tc:SAML:2.0:protocol";
+
+  /** Prefix used for the SAML 2.0 protocol XML namespace */
+  public static final String SAML2P_PREFIX = "saml2p";
+
+  /** Local location of the SAML 2.0 protocol XML schema definition. */
+  public static final String SAML2P_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "saml-schema-protocol-2.0.xsd";
+  
+  /** URI of the STORK namespace. */
+  public static final String STORK_NS_URI =
+    "urn:eu:stork:names:tc:STORK:1.0:assertion";
+
+  /** Prefix used for the STORK XML namespace */
+  public static final String STORK_PREFIX = "stork";
+
+  /** Local location of the STORK XML schema definition. */
+  public static final String STORK_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "stork-schema-assertion-1.0.xsd";
+  
+  /** URI of the STORK protocol namespace. */
+  public static final String STORKP_NS_URI =
+    "urn:eu:stork:names:tc:STORK:1.0:protocol";
+
+  /** Prefix used for the STORK protocol XML namespace */
+  public static final String STORKP_PREFIX = "storkp";
+
+  /** Local location of the STORK protocol XML schema definition. */
+  public static final String STORKP_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "stork-schema-protocol-1.0.xsd";
+  
+  /** URI of the TSL namespace. */
+  public static final String TSL_NS_URI =
+    "http://uri.etsi.org/02231/v2#";
+
+  /** Prefix used for the TSL namespace */
+  public static final String TSL_PREFIX = "tsl1";
+
+  /** Local location of the TSL schema definition. */
+  public static final String TSL_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "ts_119612v010201_xsd.xsd";	
+
+  /** URI of the TSL SIE namespace. */
+  public static final String TSL_SIE_NS_URI =
+    "http://uri.etsi.org/TrstSvc/SvcInfoExt/eSigDir-1999-93-EC-TrustedList/#";
+
+  /** Prefix used for the TSL SIE namespace */
+  public static final String TSL_SIE_PREFIX = "tslsie";
+
+  /** Local location of the TSL SIE schema definition. */
+  public static final String TSL_SIE_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "ts_119612v010201_sie_xsd.xsd";
+  
+  /** URI of the TSL additional types namespace. */
+  public static final String TSL_ADDTYPES_NS_URI =
+    "http://uri.etsi.org/02231/v2/additionaltypes#";
+
+  /** Prefix used for the TSL additional types namespace */
+  public static final String TSL_ADDTYPES_PREFIX = "tsltype";
+
+  /** Local location of the TSL additional types schema definition. */
+  public static final String TSL_ADDTYPES_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "ts_ts_119612v010201_additionaltypes_xsd.xsd";
+  
+  /** URI of the XML Encryption namespace. */
+  public static final String XENC_NS_URI =
+    "http://www.w3.org/2001/04/xmlenc#";
+
+  /** Prefix used for the XML Encryption XML namespace */
+  public static final String XENC_PREFIX = "xenc";
+
+  /** Local location of the XML Encryption XML schema definition. */
+  public static final String XENC_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "xenc-schema.xsd";
+
+  /** Prefix used for the XML Encryption XML namespace */
+  public static final String SAML2_METADATA_PREFIX = "md";
+  
+  /** Prefix used for the XML Encryption XML namespace */
+  public static final String SAML2_METADATA_URI = "urn:oasis:names:tc:SAML:2.0:metadata";
+
+  /** Local location of the XML Encryption XML schema definition. */
+  public static final String SAML2_METADATA_SCHEMA_LOCATION =
+    SCHEMA_ROOT + "saml-schema-metadata-2.0.xsd";
+  
+  
+  /* Prefix and Schema definition for eIDAS specific SAML2 extensions*/
+  public static final String SAML2_eIDAS_EXTENSIONS_PREFIX = "eidas";
+  public static final String SAML2_eIDAS_EXTENSIONS = "http://eidas.europa.eu/saml-extensions";
+  public static final String SAML2_eIDAS_EXTENSIONS_SCHEMA_LOCATION = SCHEMA_ROOT + "eIDAS_saml_extensions.xsd";
+  
+  
+  /* Prefix and Schema for SAML2 Entity Attributes */
+  public static final String SAML2_MDATTR_EXTENSIONS_PREFIX = "mdattr";
+  public static final String SAML2_MDATTR_EXTENSIONS = "urn:oasis:names:tc:SAML:metadata:attribute";
+  public static final String SAML2_MDATTR_EXTENSIONS_SCHEMA_LOCATION = SCHEMA_ROOT + "sstc-metadata-attr.xsd";
+  
+  /**
+   * Contains all namespaces and local schema locations for XML schema
+   * definitions relevant for MOA. For use in validating XML parsers.
+   */
+  public static final String ALL_SCHEMA_LOCATIONS =
+    (MOA_NS_URI + " " + MOA_SCHEMA_LOCATION + " ")
+      + (MOA_CONFIG_NS_URI + " " + MOA_CONFIG_SCHEMA_LOCATION + " ")
+      + (MOA_ID_CONFIG_NS_URI + " " + MOA_ID_CONFIG_SCHEMA_LOCATION + " ")
+      + (SL10_NS_URI + " " + SL10_SCHEMA_LOCATION + " ")
+      + (SL11_NS_URI + " " + SL11_SCHEMA_LOCATION + " ")
+      + (SL12_NS_URI + " " + SL12_SCHEMA_LOCATION + " ")
+      + (ECDSA_NS_URI + " " + ECDSA_SCHEMA_LOCATION + " ")
+      + (PD_NS_URI + " " + PD_SCHEMA_LOCATION + " ")
+      + (SAML_NS_URI + " " + SAML_SCHEMA_LOCATION + " ")
+      + (SAMLP_NS_URI + " " + SAMLP_SCHEMA_LOCATION + " ")
+      + (XML_NS_URI + " " + XML_SCHEMA_LOCATION + " ")
+      + (XSI_NS_URI + " " + XSI_SCHEMA_LOCATION + " ")
+      + (DSIG_NS_URI + " " + DSIG_SCHEMA_LOCATION + " ")
+      + (DSIG_FILTER2_NS_URI + " " + DSIG_FILTER2_SCHEMA_LOCATION + " ")
+      + (DSIG_EC_NS_URI + " " + DSIG_EC_SCHEMA_LOCATION + " ")
+      + (XMLLPR_NS_URI + " " + XMLLPR_SCHEMA_LOCATION + " ")
+      + (XADES_1_1_1_NS_URI + " " + XADES_1_1_1_SCHEMA_LOCATION + " ")
+      + (XADES_1_2_2_NS_URI + " " + XADES_1_2_2_SCHEMA_LOCATION + " ")
+      + (XADES_1_3_2_NS_URI + " " + XADES_1_3_2_SCHEMA_LOCATION + " ")
+      + (XADES_1_4_1_NS_URI + " " + XADES_1_4_1_SCHEMA_LOCATION + " ")
+      + (TSL_NS_URI + " " + TSL_SCHEMA_LOCATION + " ")
+      + (TSL_SIE_NS_URI + " " + TSL_SIE_SCHEMA_LOCATION + " ")
+      + (TSL_ADDTYPES_NS_URI + " " + TSL_ADDTYPES_SCHEMA_LOCATION + " ")
+      + (SAML2_NS_URI + " " + SAML2_SCHEMA_LOCATION + " ")
+      + (SAML2P_NS_URI + " " + SAML2P_SCHEMA_LOCATION + " ")
+      + (STORK_NS_URI + " " + STORK_SCHEMA_LOCATION + " ")
+      + (STORKP_NS_URI + " " + STORKP_SCHEMA_LOCATION + " ")
+      + (SAML2_METADATA_URI + " " + SAML2_METADATA_SCHEMA_LOCATION + " ")
+      + (XENC_NS_URI + " " + XENC_SCHEMA_LOCATION + " ")
+      + (SAML2_eIDAS_EXTENSIONS + " " + SAML2_eIDAS_EXTENSIONS_SCHEMA_LOCATION + " ")
+  	  + (SAML2_MDATTR_EXTENSIONS + " " + SAML2_MDATTR_EXTENSIONS_SCHEMA_LOCATION);
+
+  
+  /** Security Layer manifest type URI. */
+  public static final String SL_MANIFEST_TYPE_URI =
+    "http://www.buergerkarte.at/specifications/Security-Layer/20020225#SignatureManifest";
+
+  /** URI of the SHA1 digest algorithm */
+  public static final String SHA1_URI =
+    "http://www.w3.org/2000/09/xmldsig#sha1";
+  
+  /** URI of the SHA1 digest algorithm */
+  public static final String SHA256_URI =
+    "http://www.w3.org/2000/09/xmldsig#sha256";
+  
+  /** URI of the SHA1 digest algorithm */
+  public static final String SHA384_URI =
+    "http://www.w3.org/2000/09/xmldsig#sha384";
+  
+  /** URI of the SHA1 digest algorithm */
+  public static final String SHA512_URI =
+    "http://www.w3.org/2000/09/xmldsig#sha512";
+  
+  /** URI of the Canonical XML algorithm */
+  public static final String C14N_URI =
+    "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
+
+  /** URI of the Canoncial XML with comments algorithm */
+  public static final String C14N_WITH_COMMENTS_URI =
+    "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments";
+
+  /** URI of the Exclusive Canonical XML algorithm */
+  public static final String EXC_C14N_URI =
+    "http://www.w3.org/2001/10/xml-exc-c14n#";
+  
+  /** URI of the Exclusive Canonical XML with commments algorithm */
+  public static final String EXC_C14N_WITH_COMMENTS_URI =
+    "http://www.w3.org/2001/10/xml-exc-c14n#WithComments";
+    
+    /** 
+   * A map used to map namespace prefixes to namespace URIs 
+   */ 
+  public static final Map<String, String> nSMap = Collections.unmodifiableMap(new HashMap<String, String>(){
+	private static final long serialVersionUID = 3845384324295136490L;
+	  {
+	  put(XMLNamespaceConstants.SAML_PREFIX, XMLNamespaceConstants.SAML_NS_URI);
+	  put(XMLNamespaceConstants.ECDSA_PREFIX, "http://www.w3.org/2001/04/xmldsig-more#");
+	  put(XMLNamespaceConstants.DSIG_PREFIX, XMLNamespaceConstants.DSIG_NS_URI);
+  	}
+  });
+
+   
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/IGUIBuilderConfiguration.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/IGUIBuilderConfiguration.java
new file mode 100644
index 00000000..80a686f9
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/IGUIBuilderConfiguration.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.gui;
+
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * @author tlenz
+ *
+ */
+public interface IGUIBuilderConfiguration {
+	
+	
+	/**
+	 * Define the name of the template (with suffix) which should be used
+	 * 
+	 * @return templatename, but never null
+	 */
+	public String getViewName();
+	
+	/**
+	 * Define the parameters, which should be evaluated in the template
+	 * 
+	 * @return Map of parameters, which should be added to template
+	 */
+	public Map<String, Object> getViewParameters();
+	
+	
+	/**
+	 * Get a specific classpath template-directory prefix, which is used 
+	 *  to load a template from classpath by using <code>ClassLoader.getResourceAsStream(...)</code>  
+	 * 
+	 * @return Classpath directory, or null if the default directory should be used
+	 */
+	public String getClasspathTemplateDir();
+		
+	/** 
+	 * Get the GUI template with a specific name
+	 * 
+	 * @param viewName Name of the template
+	 * @return Tempate as <code>InputStream</code>, or null if default getTemplate method should be used  
+	 */
+	public InputStream getTemplate(String viewName);
+	
+	/**
+	 * Get the contentType, which should be set in HTTP response
+	 * <br><br>
+	 * <b>DefaultValue:</b> text/html;charset=UTF-8
+	 * 
+	 * @return ContentType, or null if default ContentType should be used.
+	 */
+	public String getDefaultContentType();
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/IGUIBuilderConfigurationFactory.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/IGUIBuilderConfigurationFactory.java
new file mode 100644
index 00000000..0d6b1470
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/IGUIBuilderConfigurationFactory.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.gui;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+
+public interface IGUIBuilderConfigurationFactory {
+
+	/**
+	 * Get a DefaultGuiBuilderConfiguration to render an error message 
+	 * 
+	 * @param authURL PublicURLPrefix of the IDP but never null
+	 * @return
+	 */
+	public IGUIBuilderConfiguration getDefaultErrorGUI(String authURL);
+	
+	/**
+	 * @param Current processed pending-request but never null
+	 * @param viewName Name of the default template (with suffix) but never null 
+	 * @param configRootContextDir Path to configuration root directory
+	 * @return
+	 * @throws MalformedURLException If configRootContextDir is not a valid URI
+	 */
+	public IGUIBuilderConfiguration getSPSpecificSAML2PostConfiguration(IRequest pendingReq, String viewName, URI configRootContextDir)
+			throws MalformedURLException;
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/IGUIFormBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/IGUIFormBuilder.java
new file mode 100644
index 00000000..40238c2b
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/IGUIFormBuilder.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.gui;
+
+import java.io.InputStream;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.VelocityContext;
+
+import at.gv.egiz.eaaf.core.exceptions.GUIBuildException;
+
+/**
+ * @author tlenz
+ *
+ */
+public interface IGUIFormBuilder {
+
+	/**
+	 * Parse a GUI template, with parameters into a http servlet-response 
+	 * and use the default http-response content-type.
+	 * <br><br>
+	 *  The parser use the <code>VelocityEngine</code> as internal template evaluator. 
+	 * 
+	 * @param httpResp http-response object
+	 * @param viewName Name of the template (with suffix), which should be used. 
+	 *    The template is selected by using the <code>getTemplate(String viewName)</code> method
+	 * @param viewParams Map of parameters, which should be added to template
+	 * @param loggerName String, which should be used from logger
+	 * 
+	 * @throws GUIBuildException
+	 */
+	public void build(HttpServletResponse httpResp, IGUIBuilderConfiguration config, String loggerName) throws GUIBuildException;
+
+	/**
+	 * Parse a GUI template, with parameters into a http servlet-response.
+	 * <br><br>
+	 *  The parser use the <code>VelocityEngine</code> as internal template evaluator. 
+	 * 
+	 * @param httpResp http-response object
+	 * @param viewName Name of the template (with suffix), which should be used. 
+	 *    The template is selected by using the <code>getTemplate(String viewName)</code> method
+	 * @param viewParams Map of parameters, which should be added to template
+	 * @param contentType http-response content-type, which should be set
+	 * @param loggerName String, which should be used from logger
+	 * 
+	 * @throws GUIBuildException
+	 */
+	void build(HttpServletResponse httpResp, IGUIBuilderConfiguration config, String contentType,
+			String loggerName) throws GUIBuildException;
+	
+	
+	/**
+	 * Generate a new {@link VelocityContext} and populate it with MOA-ID GUI parameters
+	 * 
+	 * @param config
+	 * @return
+	 */
+	public VelocityContext generateVelocityContextFromConfiguration(IGUIBuilderConfiguration config);
+	
+
+	/**
+	 * Load the template from different resources
+	 * 
+	 * @param config
+	 * @return An {@link InputStream} but never null. The {@link InputStream} had to be closed be the invoking method
+	 * @throws GUIBuildException
+	 */
+	public InputStream getTemplateInputStream(IGUIBuilderConfiguration config) throws GUIBuildException;
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/ModifyableGuiBuilderConfiguration.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/ModifyableGuiBuilderConfiguration.java
new file mode 100644
index 00000000..3183ffad
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/gui/ModifyableGuiBuilderConfiguration.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.gui;
+
+public interface ModifyableGuiBuilderConfiguration {
+
+	/**
+	 * Add a key/value pair into Velocity context.<br>
+	 * <b>IMPORTANT:</b> external HTML escapetion is required, because it is NOT done internally
+	 * 
+	 * @param key velocity context key
+	 * @param value of this key
+	 */
+	void putCustomParameterWithOutEscaption(String key, Object value);
+
+	/**
+	 * Add a key/value pair into Velocity context.<br>
+	 * All parameters get escaped internally
+	 * 
+	 * @param key velocity context key
+	 * @param value of this key
+	 */
+	void putCustomParameter(String key, String value);
+
+}
\ No newline at end of file
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/EAAFAuthProcessDataConstants.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/EAAFAuthProcessDataConstants.java
new file mode 100644
index 00000000..f7a9a847
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/EAAFAuthProcessDataConstants.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp;
+
+public interface EAAFAuthProcessDataConstants {
+
+	public static final String GENERIC_PREFIX 					= "generic_";
+	
+	public static final String VALUE_ISSUEINSTANT 				= "direct_issueInstant";
+	
+	public static final String FLAG_IS_AUTHENTICATED 			= "direct_flagIsAuth";
+	public static final String FLAG_IS_FOREIGNER 				= "direct_flagIsForeigner";	
+	public static final String FLAG_USE_MANDATE 				= "direct_flagUseMandate";
+	public static final String FLAG_IS_ORGANWALTER 				= "direct_flagOrganwalter";
+	
+	public static final String VALUE_IDENTITYLINK 				= "direct_idl";
+	public static final String VALUE_QAALEVEL 					= "direct_qaaLevel";	
+	public static final String VALUE_MISMANDATE 				= "direct_MIS_Mandate";
+	
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAction.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAction.java
new file mode 100644
index 00000000..c8d55b96
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAction.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ *******************************************************************************/
+/*******************************************************************************
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+
+
+/**
+ * Basic interface of a specific operation that is requested by an authentication protocol implementation
+ * 
+ * @author tlenz
+ *
+ */
+public interface IAction {
+	public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) 
+			throws EAAFException;
+	public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp);
+	
+	public String getDefaultActionName();
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAttributeBuilder.java
new file mode 100644
index 00000000..ded9731c
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAttributeBuilder.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ *******************************************************************************/
+/*******************************************************************************
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp;
+
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+
+public interface IAttributeBuilder {
+	public String getName();
+	
+	public <ATT> ATT build(final ISPConfiguration oaParam, final IAuthData authData,
+			final IAttributeGenerator<ATT> g) throws AttributeBuilderException;
+	
+	public <ATT> ATT buildEmpty(final IAttributeGenerator<ATT> g);
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAttributeGenerator.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAttributeGenerator.java
new file mode 100644
index 00000000..01bb68cc
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAttributeGenerator.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ *******************************************************************************/
+/*******************************************************************************
+
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp;
+
+public interface IAttributeGenerator<ATT> {
+	/**
+	 * 
+	 * @param friendlyName FriendlyName
+	 * @param name	Name
+	 * @param value value
+	 * @return
+	 */
+	public abstract ATT buildStringAttribute(final String friendlyName, final String name, final String value);
+	
+	public abstract ATT buildIntegerAttribute(final String friendlyName, final String name, final int value);
+	
+	public abstract ATT buildLongAttribute(final String friendlyName, final String name, final long value);
+	
+	public abstract ATT buildEmptyAttribute(final String friendlyName, final String name);
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAuthData.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAuthData.java
new file mode 100644
index 00000000..888b6e92
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAuthData.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ *******************************************************************************/
+/**
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egiz.eaaf.core.api.idp;
+
+import java.util.Date;
+
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
+
+/**
+ * @author tlenz
+ *
+ */
+public interface IAuthData {
+
+	/**
+	 * BaseId transfer policy
+	 * 
+	 * @return true if baseID transfer to service provider is allowed, otherwise false
+	 */
+	boolean isBaseIDTransferRestrication();
+
+	/**
+	 * Identifier of the IDP that authenicates the user
+	 * 
+	 * @return
+	 */
+	String getAuthenticationIssuer();
+	
+	/**
+	 * Timestamp of the authentication process
+	 * 
+	 * @return
+	 */
+	Date getAuthenticationIssueInstant();
+	
+	/**
+	 * Get string formated timestamp of the authentication process
+	 * 
+	 * @return
+	 */
+	String getAuthenticationIssueInstantString();
+	
+
+	/**
+	 * Familyname of the user
+	 * 
+	 * @return
+	 */
+	String getFamilyName();
+	
+	/**
+	 * Givenname of the user
+	 * 
+	 * @return
+	 */
+	String getGivenName();
+	
+	/**
+	 * Date of birth of the user
+	 * 
+	 * @return date of birth or null no data of birth is available
+	 */
+	Date getDateOfBirth();
+	
+	/**
+	 * String formated date of birth of the user with pattern yyyy-MM-dd 
+	 * 
+	 * 
+	 * @return date of birth or '2999-12-31' if no data of birth is available
+	 */
+	String getFormatedDateOfBirth();
+
+	/**
+	 * Get bPK of the user
+	 * 
+	 * @return
+	 */
+	String getBPK();
+	
+	/**
+	 * Get sector for user's bPK
+	 * 
+	 * 
+	 * @return Sector identifier with prefix
+	 */
+	String getBPKType();
+	 	 	 	
+	/**
+	 * Get baseId of this user
+	 * 
+	 * @return
+	 */
+	String getIdentificationValue();
+	
+	/**
+	 * Get type identifier of the baseId
+	 * By default, this type is urn:publicid:gv.at:baseid
+	 * 
+	 * @return
+	 */
+	String getIdentificationType();
+	 
+
+	/**
+	 * Get the identityLink for the authenticated user
+	 * 
+	 * @return IDL, or NULL if no IDL is available
+	 */
+	IIdentityLink getIdentityLink();
+	
+	 /**
+	  * Return LoA for this user authentication
+	  *  
+	  * @return eIDAS LoA URI 
+	  */
+	 public String getEIDASQAALevel();
+
+	
+	 /**
+	  * Indicates that the user is a foreigner 
+	  * 
+	  * @return true if the user is foreigner, otherwise false
+	  */
+	 boolean isForeigner();
+	 
+	 /**
+	  * Code of the citizen country of the authenticated user 
+	  * 
+	  * @return
+	  */
+	 String getCiticenCountryCode();
+
+
+	 /**
+	  * Indicate that the authentication was done by using an active single sign-on session 
+	  * 
+	  * @return true if it an SSO session was used, otherwise false
+	  */
+	 boolean isSsoSession();
+	 
+	 /**
+	  * Date, up to which the SSO that was used for authentication is valid to
+	  * 
+	  * @return
+	  */
+ 	 Date getSsoSessionValidTo();
+
+	 	 
+ 	 /**
+ 	  * SessionIndex, if it was an reauthentication on a service provider by using the same SSO session  
+ 	  * 
+ 	  * @return
+ 	  */
+	 String getSessionIndex();
+	 
+	 /**
+	  * SAML2 NameID for the user 
+	  * 
+	  * @return
+	  */
+	 String getNameID(); 
+	 
+	 /**
+	  * Format of the SAML2 NameID 
+	  * 
+	  * @return
+	  */
+	 String getNameIDFormat();
+	 
+	 	 	 
+	 /**
+	  * Get generic information for this authenticated user
+	  * 
+	  * @param key Identifier for the generic data
+	  * @param clazz Type of the generic data
+	  * @return return the generic data of specific type, otherwise null
+	  */
+	 public <T> T getGenericData(String key, final Class<T> clazz);
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAuthenticationDataBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAuthenticationDataBuilder.java
new file mode 100644
index 00000000..4bdefb06
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAuthenticationDataBuilder.java
@@ -0,0 +1,14 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException;
+
+public interface IAuthenticationDataBuilder {
+
+	IAuthData buildAuthenticationData(IRequest pendingReq) throws EAAFAuthenticationException;
+
+	
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IConfiguration.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IConfiguration.java
new file mode 100644
index 00000000..6aac90f8
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IConfiguration.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.Map;
+import java.util.Properties;
+
+import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+
+public interface IConfiguration {
+	
+	public static final String CONFIG_PROPS_AUTH_DEFAULT_COUNTRYCODE = "configuration.auth.default.countrycode";
+	
+	/**
+	 * Get a configuration value from file based configuration
+	 * 
+	 * @param key configuration key 
+	 * @return configuration value or null if it is not found
+	 */
+	public String getBasicConfiguration(final String key);
+	
+	
+	/**
+	 * Get a configuration value from file based configuration
+	 * 
+	 * @param key configuration key 
+	 * @param defaultValue Default value if no value with this key is found
+	 * @return configuration value 
+	 */
+	public String getBasicConfiguration(final String key, final String defaultValue);
+	
+	/**
+	 * Get a set of configuration values from file based configuration that starts with this prefix
+	 * <br><br>
+	 * <b>Important:</b> The configuration values must be of type String! 
+	 * 
+	 * @param prefix Prefix of the configuration key
+	 * @return Map<String, String> without prefix, but never null
+	 */
+	public Map<String, String> getBasicMOAIDConfigurationWithPrefix(final String prefix);
+	
+	
+	/**
+	 * Get a boolean value from basic MOA-ID configuration file
+	 * 
+	 * @param key Configuration key
+	 * @param defaultValue Default result
+	 * @return returns the value of the configuration key, or the default value if the key is not set
+	 */
+	public boolean getBasicMOAIDConfigurationBoolean(String key, boolean defaultValue);
+	
+	/**
+	 * Get a configuration entry for a specific Service Provider 
+	 * 
+	 * @param uniqueID Unique identifier of the Service Provider
+	 * @return 
+	 * @throws EAAFConfigurationException 
+	 */
+	public ISPConfiguration getServiceProviderConfiguration(final String uniqueID) throws EAAFConfigurationException; 
+	
+	
+	/**
+	 * Get a configuration entry for a specific Service Provider that is decorated by a Object
+	 * 
+	 * @param spIdentifier EntityID of a Service Provider 
+	 * @param decorator Decorator that should be used to decorate the result. 
+  	 *                  This decorator has to be implement or extend the {@link ISPConfiguration} interface
+	 * @return
+	 * @throws EAAFConfigurationException
+	 */
+    public <T> T getServiceProviderConfiguration(String spIdentifier, final Class<T> decorator) throws EAAFConfigurationException;
+	
+	/**
+	 * Get the full configuration properties object
+	 * 
+	 * @return 
+	 */
+	public Properties getFullConfigurationProperties();
+	
+	/**
+	 * Get the root directory of the configuration folder
+	 * 
+	 * @return 
+	 */
+	public URI getConfigurationRootDirectory();
+	
+		
+	/**
+	 * Get the path to EAAFCore configuration that is internally used
+	 * 
+	 * @return
+	 */
+	public URI getConfigurationFilePath();
+
+
+	/**
+	 * Validate a URL if it it is allowed by configuration.
+	 * 
+	 * @param authReqUrl URL for validation
+	 * @return URL of the application context if the authReqUrl was valid, otherwise null 
+	 */
+	public String validateIDPURL(URL authReqUrl) throws EAAFException;
+	
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IModulInfo.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IModulInfo.java
new file mode 100644
index 00000000..03a761f2
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IModulInfo.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ *******************************************************************************/
+/*******************************************************************************
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+
+/**
+ * Basic interface of an authentication protocol implementation on IDP side
+ * 
+ * @author tlenz
+ *
+ */
+public interface IModulInfo {
+	
+	/**
+	 * Name of this IDP authentication module
+	 * 
+	 * @return
+	 */
+	public String getName();
+	
+	/**
+	 * Authentication protocol identifier for this module
+	 * 
+	 * @return
+	 */
+	public String getAuthProtocolIdentifier();
+	
+	/**
+	 * Generates a protocol specific error message
+	 * 
+	 * 
+	 * @param e Exception that contains the error message
+	 * @param request httpRequest object from servlet container
+	 * @param response httpResponse object from servlet container
+	 * @param protocolRequest incoming protocol request
+	 * @return return <i>true</i> if a protocol specific error message was generated, otherwise <i>false</i>
+	 * @throws Throwable
+	 */
+	public boolean generateErrorMessage(Throwable e,
+			HttpServletRequest request, HttpServletResponse response,
+			IRequest protocolRequest) throws Throwable;
+	
+	/**
+	 * additional validation of a incoming authentication request 
+	 * 
+	 * @param request httpRequest object from servlet container
+	 * @param response httpResponse object from servlet container
+	 * @param pending incoming protocol request
+	 * @return return <i>true</i> if the incoming request is valid, otherwise <i>false</i>
+	 */
+	public boolean validate(HttpServletRequest request, 
+			HttpServletResponse response, IRequest pending);
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IPVPAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IPVPAttributeBuilder.java
new file mode 100644
index 00000000..33693647
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IPVPAttributeBuilder.java
@@ -0,0 +1,9 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp;
+
+import at.gv.egiz.eaaf.core.api.data.PVPAttributeDefinitions;
+
+public interface IPVPAttributeBuilder extends PVPAttributeDefinitions, IAttributeBuilder {
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/ISPConfiguration.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/ISPConfiguration.java
new file mode 100644
index 00000000..82e4bd1e
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/ISPConfiguration.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+
+public interface ISPConfiguration extends Serializable {
+
+	public static final String CONFIG_KEY_RESTRICTIONS_BASEID_INTERNAL = "configuration.restrictions.baseID.idpProcessing";
+	public static final String CONFIG_KEY_RESTRICTIONS_BASEID_TRANSMISSION = "configuration.restrictions.baseID.spTransmission";
+	
+	/**
+	 * Get the full key/value configuration for this Service Provider
+	 * 
+	 * @return an unmodifiable map of key/value pairs
+	 */
+	public Map<String, String> getFullConfiguration();
+	
+	  /**
+	   * Get a configuration value from Service Provider key/value configuration
+	   * 
+	   * @param key The key identifier of a configuration value 
+	   * @return The configuration value {String} or null if the key does not exist
+	   */  
+	public String getConfigurationValue(String key);
+
+	  /**
+	   * Get a configuration value from Service Provider key/value configuration
+	   * 
+	   * @param key The key identifier of a configuration value 
+	   * @param defaultValue Default value if key does not exist
+	   * @return The configuration value {String} or defaultValue if the key does not exist
+	   */  
+	public String getConfigurationValue(String key, String defaultValue);
+	
+	/**
+	 * Get a boolean configuration value from Service Provider key/value configuration
+	 * 
+	 * @param key The key identifier of a configuration value 
+	 * @return true / false, or null if the key does not exist
+	 */
+	public Boolean isConfigurationValue(String key);
+	
+	
+	/**
+	 * Get a boolean configuration value from Service Provider key/value configuration
+	 * 
+	 * @param key The key identifier of a configuration value 
+	 * @param defaultValue Default value if key does not exist
+	 * @return true / false, or defaultValue if the key does not exist
+	 */
+	public boolean isConfigurationValue(String key, boolean defaultValue);
+	
+	/**
+	 * Check if a configuration key is available in this Service Provider configuration 
+	 * 
+	 * @param key The key identifier of a configuration value
+	 * @return true if the configuration key exists, otherwise false
+	 */
+	boolean containsConfigurationKey(String key);
+	
+	/**
+	 * Return the unique identifier of this Service Provider
+	 * 
+	 * @return
+	 */
+	public String getUniqueIdentifier();
+	
+	/**
+	 * Return the unique identifier of this Service Provider
+	 * 
+	 * @return
+	 */
+	public String getFriendlyName();
+	
+	/**
+	 * Indicates if this service provider has private area restrictions that disallow baseId processing in general
+	 * 	 * 
+	 * @return true if there is a restriction, otherwise false
+	 */
+	public boolean hasBaseIdInternalProcessingRestriction();
+	
+	
+	/**
+	 * Indicates if this service provider has private area restrictions that disallow baseId transfer to SP
+	 *  
+	 * @return true if there is a restriction, otherwise false
+	 */
+	public boolean hasBaseIdTransferRestriction();
+	
+	/**
+	 * Get the {@link List} of identifier's that indicates no baseID processing restriction exists.<br>  
+	 * This list can be configured by key: "configuration.restrictions.baseID.idpProcessing"
+	 * 
+	 * @return
+	 */
+	public List<String> getTargetsWithNoBaseIdInternalProcessingRestriction();
+	
+	/**
+	 * Get the {@link List} of identifier's that indicates no baseID transfer restriction exists.<br>  
+	 * This list can be configured by key: "configuration.restrictions.baseID.spTransmission"
+	 * 
+	 * @return
+	 */
+	public List<String> getTargetsWithNoBaseIdTransferRestriction();
+	
+	/**
+	 * Get the minimum eIDAS LoA that is required by this service provider
+	 * 
+	 * {@link EAAFConstants.EIDAS_QAA_LOW}
+	 * {@link EAAFConstants.EIDAS_QAA_SUBSTANTIAL}
+	 * {@link EAAFConstants.EIDAS_QAA_HIGH}
+	 * 
+	 * @return return eIDAS LoA
+	 */
+	public String getMinimumLevelOfAssurence();
+	
+	/**
+	 * Get the full area-identifier for this service provider to calculate the 
+	 * area-specific unique person identifier (bPK, wbPK, eIDAS unique identifier, ...). 
+	 * This identifier always contains the full prefix 
+	 * 
+	 * @return area identifier with prefix  
+	 */
+	public String getAreaSpecificTargetIdentifier();
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/IAuthenticationManager.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/IAuthenticationManager.java
new file mode 100644
index 00000000..82f87f49
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/IAuthenticationManager.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp.auth;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.slo.ISLOInformationContainer;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+
+public interface IAuthenticationManager {
+	
+	//TODO
+	public static int EVENT_AUTHENTICATION_PROCESS_FOR_SP = -1;
+	public static int EVENT_AUTHENTICATION_PROCESS_STARTED = -1;
+	public static int EVENT_AUTHENTICATION_PROCESS_FINISHED = -1;
+	public static int EVENT_AUTHENTICATION_PROCESS_ERROR = -1;
+	
+		
+	/**
+	 * Add a request parameter to whitelist. All parameters that are part of the white list are added into {@link ExecutionContext} 
+	 * 
+	 * @param httpReqParam http parameter name, but never null
+	 */
+	void addParameterNameToWhiteList(String httpReqParam);
+
+	/**
+	 * Add a request header to whitelist. All parameters that are part of the white list are added into {@link ExecutionContext} 
+	 * 
+	 * @param httpReqParam http header name, but never null
+	 */
+	void addHeaderNameToWhiteList(String httpReqParam);
+	
+
+	/**
+	 * Starts an authentication process for a specific pending request
+	 * 
+	 * @param httpReq http servlet request
+	 * @param httpResp http servlet response
+	 * @param pendingReq Pending request for that an authentication is required
+	 * @return true if the pending request is already authenticated, otherwise false
+	 * @throws EAAFException
+	 */
+	boolean doAuthentication(HttpServletRequest httpReq, HttpServletResponse httpResp,
+			IRequest pendingReq) throws EAAFException;
+	
+	/**
+	 * Close an active authenticated session on IDP side
+	 * 
+	 * @param request http servlet request
+	 * @param response http servlet response
+	 * @param pendingReq ReqPending request for that an authentication session should be closed
+	 */
+	void performOnlyIDPLogOut(HttpServletRequest request, HttpServletResponse response, IRequest pendingReq);
+	
+		
+	/**
+	 * Close an active authenticated session on IDP side and get a list authenticated service providers
+	 * 
+	 * @param request http servlet request
+	 * @param response http servlet response
+	 * @param pendingReq ReqPending request for that an authentication session should be closed
+	 * @param internalSSOId internal SSO session identifier 
+	 * @return A container that contains all active SP sessions
+	 * @throws EAAFException
+	 */
+	ISLOInformationContainer performSingleLogOut(HttpServletRequest httpReq, HttpServletResponse httpResp, IRequest pendingReq, String internalSSOId) throws EAAFException;
+
+	
+}
\ No newline at end of file
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/ISSOManager.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/ISSOManager.java
new file mode 100644
index 00000000..9c7a7320
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/ISSOManager.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp.auth;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface;
+import at.gv.egiz.eaaf.core.exceptions.EAAFSSOException;
+
+public interface ISSOManager {
+	
+	//TODO
+	public static int EVENT_SSO_SESSION_INVALID = -1;
+	public static int EVENT_SSO_SESSION_VALID = -1;
+	
+	
+	public static final String PROCESS_ENGINE_SSO_CONSENTS_EVALUATION = "ssoconsentsevaluation";
+	public static final String AUTH_DATA_SSO_SESSIONID	= "eaaf_authdata_sso_sessionId";
+	
+	
+	/**
+	 * Check if there is an active and valid SSO session for the current pending request.
+	 * <br>
+	 * If there is an active SSO session, the pending request will be populated with eID information from SSO session 
+	 * 
+	 * @param pendingReq Current incoming pending request
+	 * @param httpReq http Servlet request
+	 * @param httpResp http Servlet response
+	 * @return true if there is a valid SSO session, otherwise false
+	 * @throws EAAFSSOException
+	 */
+	public boolean checkAndValidateSSOSession(IRequest pendingReq, HttpServletRequest httpReq, HttpServletResponse httpResp) throws EAAFSSOException;
+	
+	/**
+	 * Populate service provider specific SSO settings
+	 * 
+	 * Check if Single Sign-On is allowed for the current pending request and the requested service provider 
+	 * 
+	 * @param pendingReq Current incoming pending request
+	 * @param httpReq http Servlet request
+	 * @return true if SSO is allowed for this service provider, otherwise false
+	 */
+	public void isSSOAllowedForSP(IRequest pendingReq, HttpServletRequest httpReq);
+	
+	
+	/**
+	 * Populate the current pending request with eID information from an existing SSO session 
+	 * 
+	 * @param pendingReq pending request that should be populated by SSO session
+	 * @throws EAAFSSOException if pending request contains no SSO information or population failed
+	 */
+	public void populatePendingRequestWithSSOInformation(IRequest pendingReq) throws EAAFSSOException;
+	
+	
+	/**
+	 * Destroy an active SSO session on IDP site only
+	 * 
+	 * @param httpReq http servlet request
+	 * @param httpResp http servlet response
+	 * @param pendingReq 
+	 * @return true if a SSO session was closed successfully, otherwise false
+	 * @throws EAAFSSOException in case of an internal processing error
+	 */
+	public boolean destroySSOSessionOnIDPOnly(HttpServletRequest httpReq, HttpServletResponse httpResp, IRequest pendingReq) throws EAAFSSOException;
+	
+	
+	
+	// ************************* old ***************************************************	
+	String createNewSSOSessionCookie(HttpServletRequest req, HttpServletResponse resp, IRequest pendingReq)  throws EAAFSSOException;
+
+	
+	void createNewSSOSession(IRequest pendingReq, String newSSOSessionId, SLOInformationInterface sloInformation) throws EAAFSSOException;
+//	{
+//		internalDBSSOSession = authenticatedSessionStorage.createInternalSSOSession(pendingReq);				
+//		authenticatedSessionStorage.addSSOInformation(internalDBSSOSession.getSessionID(), 
+//				newSSOSessionId, sloInformation, pendingReq);	
+//
+//	}
+
+
+	void updateSSOSession(IRequest pendingReq, String newSSOSessionId, SLOInformationInterface sloInformation)  throws EAAFSSOException;
+//	{
+//		authenticatedSessionStorage.addSSOInformation(moaSession.getSessionID(), 
+//				newSSOSessionId, sloInformation, pendingReq);
+//	}
+
+
+
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/data/IAuthProcessDataContainer.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/data/IAuthProcessDataContainer.java
new file mode 100644
index 00000000..743c7797
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/data/IAuthProcessDataContainer.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp.auth.data;
+
+import java.util.Date;
+import java.util.Map;
+
+import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException;
+
+public interface IAuthProcessDataContainer {
+
+	/**
+	 * Returns the issuing time of the AUTH-Block SAML assertion.
+	 * 
+	 * @return The issuing time of the AUTH-Block SAML assertion.
+	 */
+	String getIssueInstant();
+
+	/**
+	 * Sets the issuing time of the AUTH-Block SAML assertion.
+	 * 
+	 * @param issueInstant
+	 *            The issueInstant to set.
+	 */
+	void setIssueInstant(String issueInstant);
+	
+	/**
+	 * Indicate if the authentication process is finished
+	 * 
+	 * @return
+	 */
+	boolean isAuthenticated();
+
+	/**
+	 * Mark the authentication as authenticated, which means that the authenication process is completed
+	 * 
+	 * @param authenticated
+	 */
+	void setAuthenticated(boolean authenticated);
+	
+	/**
+	 * Returns the identityLink.
+	 * 
+	 * @return IdentityLink
+	 */
+	IIdentityLink getIdentityLink();
+	
+	/**
+	 * Sets the identityLink.
+	 * 
+	 * @param identityLink
+	 *            The identityLink to set
+	 */
+	void setIdentityLink(IIdentityLink identityLink);
+	
+
+	/**
+	 * Indicate that mandates was used in this auth. process
+	 * 
+	 * @return
+	 */
+	boolean isMandateUsed();
+	
+	/**
+	 * Mark that mandates was used in this auth. process
+	 * 
+	 * @param useMandates
+	 */
+	void setUseMandates(boolean useMandates);
+
+	/**
+	 * Indicate that the auth. process was performed by a foreigner
+	 * 
+	 * @return
+	 */
+	boolean isForeigner();
+
+	/**
+	 * Mark that the auth. process was done by a foreigner
+	 * 
+	 * @param isForeigner
+	 */
+	void setForeigner(boolean isForeigner);
+	
+	/**
+	 * Indicate that the auth. process was performed by an official representatives 
+	 * 
+	 * @return is official representatives 
+	 */
+	boolean isOW();
+
+	/**
+	 * Mark that the auth. process was done by an official representatives 
+	 *            
+	 */
+	void setOW(boolean isOW);
+	
+	/**
+	 * eIDAS QAA level
+	 * 
+	 * @return the qAALevel
+	 */
+	String getQAALevel();
+
+	/**
+	 * set QAA level in eIDAS form
+	 * 
+	 * @param qAALevel the qAALevel to set
+	 */
+	void setQAALevel(String qAALevel);
+
+	/**
+	 * @return the sessionCreated
+	 */
+	Date getSessionCreated();
+
+	Map<String, Object> getGenericSessionDataStorage();
+
+	/**
+	 * Returns a generic session-data object with is stored with a specific identifier 
+	 * 
+	 * @param key The specific identifier of the session-data object
+	 * @return The session-data object or null if no data is found with this key
+	 */
+	Object getGenericDataFromSession(String key);
+
+	/**
+	 * Returns a generic session-data object with is stored with a specific identifier 
+	 * 
+	 * @param key The specific identifier of the session-data object
+	 * @param clazz The class type which is stored with this key
+	 * @return The session-data object or null if no data is found with this key
+	 */
+	<T> T getGenericDataFromSession(String key, Class<T> clazz);
+
+	/**
+	 * Store a generic data-object to session with a specific identifier
+	 * 
+	 * @param key Identifier for this data-object
+	 * @param object Generic data-object which should be stored. This data-object had to be implement the 'java.io.Serializable' interface
+	 * @throws EAAFStorageException Error message if the data-object can not stored to generic session-data storage
+	 */
+	void setGenericDataToSession(String key, Object object) throws EAAFStorageException;
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/data/IIdentityLink.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/data/IIdentityLink.java
new file mode 100644
index 00000000..ca1f145d
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/data/IIdentityLink.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp.auth.data;
+
+import java.io.IOException;
+import java.security.PublicKey;
+
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Element;
+
+/**
+ * @author tlenz
+ *
+ */
+public interface IIdentityLink {
+
+	/**
+	   * Returns the dateOfBirth.
+	   * @return Calendar
+	   */
+	String getDateOfBirth();
+
+	/**
+	   * Returns the familyName.
+	   * @return String
+	   */
+	String getFamilyName();
+
+	/**
+	   * Returns the givenName.
+	   * @return String
+	   */
+	String getGivenName();
+
+	/**
+	   * Returns the name.
+	   * @return The name.
+	   */
+	String getName();
+
+	/**
+	   * Returns the identificationValue.
+		 * <code>"identificationValue"</code> is the translation of <code>"Stammzahl"</code>.
+	   * @return String
+	   */
+	String getIdentificationValue();
+
+	/**
+	 * Returns the identificationType.
+	 * <code>"identificationType"</code> type of the identificationValue in the IdentityLink.
+	 * @return String
+	 */
+	String getIdentificationType();
+
+	/**
+	   * Sets the dateOfBirth.
+	   * @param dateOfBirth The dateOfBirth to set
+	   */
+	void setDateOfBirth(String dateOfBirth);
+
+	/**
+	   * Sets the familyName.
+	   * @param familyName The familyName to set
+	   */
+	void setFamilyName(String familyName);
+
+	/**
+	   * Sets the givenName.
+	   * @param givenName The givenName to set
+	   */
+	void setGivenName(String givenName);
+
+	/**
+	   * Sets the identificationValue.
+		 * <code>"identificationValue"</code> is the translation of <code>"Stammzahl"</code>.
+	   * @param identificationValue The identificationValue to set
+	   */
+	void setIdentificationValue(String identificationValue);
+
+	/**
+	 * Sets the Type of the identificationValue.
+	 * @param identificationType The type of identificationValue to set
+	 */
+	void setIdentificationType(String identificationType);
+
+	/**
+	   * Returns the samlAssertion.
+	   * @return Element
+	   */
+	Element getSamlAssertion();
+
+	/**
+	   * Returns the samlAssertion.
+	   * @return Element
+	   */
+	String getSerializedSamlAssertion();
+
+	/**
+	   * Sets the samlAssertion and the serializedSamlAssertion.
+	   * @param samlAssertion The samlAssertion to set
+	   */
+	void setSamlAssertion(Element samlAssertion) throws TransformerException, IOException;
+
+	/**
+	   * Returns the dsigReferenceTransforms.
+	   * @return Element[]
+	   */
+	Element[] getDsigReferenceTransforms();
+
+	/**
+	   * Sets the dsigReferenceTransforms.
+	   * @param dsigReferenceTransforms The dsigReferenceTransforms to set
+	   */
+	void setDsigReferenceTransforms(Element[] dsigReferenceTransforms);
+
+	/**
+	   * Returns the publicKey.
+	   * @return PublicKey[]
+	   */
+	PublicKey[] getPublicKey();
+
+	/**
+	   * Sets the publicKey.
+	   * @param publicKey The publicKey to set
+	   */
+	void setPublicKey(PublicKey[] publicKey);
+
+	/**
+	   * Returns the prPerson.
+	   * @return Element
+	   */
+	Element getPrPerson();
+
+	/**
+	   * Sets the prPerson.
+	   * @param prPerson The prPerson to set
+	   */
+	void setPrPerson(Element prPerson);
+
+	/**
+	   * Returns the issuing time of the identity link SAML assertion.
+	   *
+	   * @return The issuing time of the identity link SAML assertion.
+	   */
+	String getIssueInstant();
+
+	/**
+	   * Sets the issuing time of the identity link SAML assertion.
+	   *
+	   * @param issueInstant The issueInstant to set.
+	   */
+	void setIssueInstant(String issueInstant);
+
+}
\ No newline at end of file
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/modules/AuthModule.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/modules/AuthModule.java
new file mode 100644
index 00000000..d8f15aff
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/modules/AuthModule.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp.auth.modules;
+
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.ProcessDefinition;
+
+/**
+ * Provides metadata of a certain module. Uses for module discovery and process selection.
+ */
+public interface AuthModule {
+
+	/**
+	 * Returns the priority of the module. The priority defines the order of the respective module within the chain of
+	 * discovered modules. Higher priorized modules are asked before lower priorized modules for a process that they can
+	 * handle.
+	 * <p/>
+	 * Internal default modules are priorized neutral ({@code 0}. Use a higher priority ({@code 1...Integer.MAX_VALUE})
+	 * in order to have your module(s) priorized or a lower priority ({@code Integer.MIN_VALUE...-1}) in order to put
+	 * your modules behind default modules.
+	 * 
+	 * @return the priority of the module.
+	 */
+	int getPriority();
+
+	/**
+	 * Selects a process (description), referenced by its unique id, which is able to perform authentication with the
+	 * given {@link ExecutionContext}. Returns {@code null} if no appropriate process (description) was available within
+	 * this module.
+	 * 
+	 * @param context
+	 *            an ExecutionContext for a process.
+	 * @return the process-ID of a process which is able to work with the given ExecutionContext, or {@code null}.
+	 */
+	String selectProcess(ExecutionContext context);
+
+	/**
+	 * Returns the an Array of {@link ProcessDefinition}s of the processes included in this module.
+	 * 
+	 * @return an array of resource uris of the processes included in this module.
+	 */
+	String[] getProcessDefinitions();
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ExecutionContext.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ExecutionContext.java
new file mode 100644
index 00000000..e5e2011b
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ExecutionContext.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp.process;
+
+import java.io.Serializable;
+import java.util.Set;
+
+/**
+ * Encapsulates data needed for or provided by task execution.
+ * 
+ * @author tknall
+ * 
+ */
+public interface ExecutionContext extends Serializable {
+
+	/**
+	 * Returns the identifier of underlying process instance.
+	 * 
+	 * @return The identifier of the process instance.
+	 */
+	String getProcessInstanceId();
+
+	/**
+	 * Sets the identifier of underlying process instance.
+	 * 
+	 * @param processInstanceId
+	 *            The identifier of the process instance.
+	 */
+	void setProcessInstanceId(String processInstanceId);
+
+	/**
+	 * Stores a serializable object using {@code key}.
+	 * 
+	 * @param key
+	 *            The key under that the {@code object} should be stored.
+	 * @param object The object to be stored.
+	 */
+	void put(String key, Serializable object);
+
+	/**
+	 * Returns an serializable object stored within this process context using {@code key}.
+	 * 
+	 * @param key
+	 *            The key that has been used to store the serializable object (may be {@code null}).
+	 * @return The object or {@code null} in case the key does not relate to a stored object or the stored object itself
+	 *         was {@code null}.
+	 */
+	Serializable get(String key);
+	
+	/**
+	 * Removes the object stored using {@code key}.
+	 * @param key
+	 *            The key that has been used to store the serializable object (may be {@code null}).
+	 * @return The object that has been removed or {@code null} there was no object stored using {@code key}.
+	 */
+	Serializable remove(String key);
+
+	/**
+	 * Returns an unmodifiable set containing the stored keys.
+	 * 
+	 * @return The keyset (never {@code null}).
+	 */
+	Set<String> keySet();
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ExpressionEvaluationContext.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ExpressionEvaluationContext.java
new file mode 100644
index 00000000..6e976422
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ExpressionEvaluationContext.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp.process;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import at.gv.egiz.eaaf.core.impl.idp.process.model.Transition;
+
+/**
+ * Context used for evaluation of condition expressions set for {@linkplain Transition Transitions}.
+ * 
+ * @author tknall
+ * 
+ */
+public interface ExpressionEvaluationContext extends Serializable {
+
+	/**
+	 * Returns the context data map used for expression evaluation.
+	 * 
+	 * @return An unmodifiable map (never {@code null}).
+	 */
+	Map<String, Serializable> getCtx();
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ExpressionEvaluator.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ExpressionEvaluator.java
new file mode 100644
index 00000000..eda6b3cb
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ExpressionEvaluator.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp.process;
+
+/**
+ * Evaluates a given {@code expression} returning a boolean value.
+ * 
+ * @author tknall
+ */
+public interface ExpressionEvaluator {
+
+	/**
+	 * Evaluates a given {@code expression} returning a boolean value.
+	 * 
+	 * @param expressionContext
+	 *            The context which can be used for evaluation of the expression.
+	 * @param expression
+	 *            The expression resulting in a boolean (must not be {@code null}).
+	 * @return A boolean value.
+	 * @throws IllegalArgumentException
+	 *             In case of an invalid {@code expression}.
+	 * @throws NullPointerException
+	 *             In case of a {@code null} expression.
+	 */
+	boolean evaluate(ExpressionEvaluationContext expressionContext, String expression);
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ProcessEngine.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ProcessEngine.java
new file mode 100644
index 00000000..523eb8dc
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ProcessEngine.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp.process;
+
+
+import java.io.InputStream;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.exceptions.ProcessExecutionException;
+import at.gv.egiz.eaaf.core.impl.idp.process.ProcessDefinitionParserException;
+import at.gv.egiz.eaaf.core.impl.idp.process.ProcessInstance;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.ProcessDefinition;
+
+/**
+ * Process engine providing means for starting and resuming processes.
+ * 
+ * @author tknall
+ */
+public interface ProcessEngine {
+
+	/**
+	 * Registers a new process definition. Note that existing definitions with the same identifier will be replaced.
+	 * 
+	 * @param processDefinition
+	 *            The process definition to be registered.
+	 */
+	void registerProcessDefinition(ProcessDefinition processDefinition);
+
+	/**
+	 * Registers a new process definition given as {@link InputStream}. Note that existing definitions with the same identifier will be replaced.
+	 *
+	 * @param processDefinitionInputStream The input stream to the definition to be registered.
+	 * @throws ProcessDefinitionParserException Thrown in case of an error parsing the process definition.
+	 * @return The process definition's identifier.
+	 */
+	String registerProcessDefinition(InputStream processDefinitionInputStream) throws ProcessDefinitionParserException;
+
+	/**
+	 * Creates a process instance according to the referenced process definition, persists it into the database and returns it identifier.
+	 * <p/>
+	 * Note that the method returns the identifier of a process instance which will be needed in order to start a process or to continue
+	 * process execution after asynchronous task execution (refer to {@link #start(String)} and
+	 * {@link #signal(String)} for further information).
+	 * 
+	 * @param processDefinitionId
+	 *            The identifier of the respective process definition.
+	 * @param executionContext The execution context (may be {@code null}).
+	 * @return The id of the newly created process instance (never {@code null}).
+	 * @throws ProcessExecutionException
+	 *             Thrown in case of error, e.g. when a {@code processDefinitionId} is referenced that does not exist.
+	 */
+	String createProcessInstance(String processDefinitionId, ExecutionContext executionContext) throws ProcessExecutionException;
+
+	/**
+	 * Creates a process instance according to the referenced process definition, persists it into the database and returns it identifier.
+	 * <p/>
+	 * Note that the method returns the identifier of a process instance which will be needed in order to start a process or to continue
+	 * process execution after asynchronous task execution (refer to {@link #start(String)} and
+	 * {@link #signal(String)} for further information).
+	 * 
+	 * @param processDefinitionId
+	 *            The identifier of the respective process definition.
+	 * @return The id of the newly created process instance (never {@code null}).
+	 * @throws ProcessExecutionException
+	 *             Thrown in case of error, e.g. when a {@code processDefinitionId} is referenced that does not exist.
+	 */
+	String createProcessInstance(String processDefinitionId) throws ProcessExecutionException;
+
+	
+	/**
+	 * Delete a process instance 
+	 * 
+	 * @param processInstanceId
+	 *            The identifier of the respective process.
+	 * @throws ProcessExecutionException
+	 *             Thrown in case of error, e.g. when a {@code processInstanceId} is referenced that does not exist.
+	 */
+	void deleteProcessInstance(String processInstanceId) throws ProcessExecutionException;
+	
+	/**
+	 * Returns the process instance with a given {@code processInstanceId}.
+	 * 
+	 * @param processInstanceId
+	 *            The process instance id.
+	 * @return The process instance (never {@code null}).
+	 * @throws IllegalArgumentException
+	 *             In case the process instance does not/no longer exist.
+	 * @throws RuntimeException
+	 *             In case the process instance could not be retrieved from persistence.
+	 */
+	ProcessInstance getProcessInstance(String processInstanceId);
+
+	/**
+	 * Starts the process using the given {@code pendingReq}.
+	 * 
+	 * @param pendingReq
+	 *            The protocol request for which a process should be started.
+	 * @throws ProcessExecutionException
+	 *             Thrown in case of error.
+	 */
+	void start(IRequest pendingReq) throws ProcessExecutionException;
+
+
+	/**
+	 * Resumes process execution after an asynchronous task has been executed.
+	 * 
+	 * @param pendingReq
+	 *            The process instance id.
+	 * @throws ProcessExecutionException
+	 *             Thrown in case of error.
+	 */
+	void signal(IRequest pendingReq) throws ProcessExecutionException;
+
+}
\ No newline at end of file
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ProcessInstanceStoreDAO.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ProcessInstanceStoreDAO.java
new file mode 100644
index 00000000..1242620b
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/ProcessInstanceStoreDAO.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp.process;
+
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException;
+import at.gv.egiz.eaaf.core.impl.idp.process.ProcessInstance;
+import at.gv.egiz.eaaf.core.impl.idp.process.dao.ProcessInstanceStore;
+
+public interface ProcessInstanceStoreDAO {
+
+	/**
+	 * Stores a {@link ProcessInstance} defined by {@code pIStore} in the
+	 * database.
+	 * 
+	 * @param pIStore
+	 *            the {@link ProcessInstanceStore} to persist.
+	 * @throws EAAFStorageException
+	 *             is thrown if a problem occurs while accessing the database.
+	 */
+	void saveOrUpdate(ProcessInstanceStore pIStore) throws EAAFException;
+
+	/**
+	 * Returns a {@link ProcessInstanceStore}, defined by
+	 * {@code processInstanceID} from the database, or {@code null} if the
+	 * object could not be found.
+	 * 
+	 * @param processInstanceId
+	 *            the id of the {@code ProcessInstanceStore} to retrieve.
+	 * @return a ProcessInstanceStore, or {@code null}.
+	 * @throws EAAFStorageException
+	 *             is thrown if a problem occurs while accessing the database.
+	 */
+	ProcessInstanceStore load(String processInstanceId) throws EAAFException;
+
+	/**
+	 * Deletes the {@link ProcessInstance} corresponding with the
+	 * {@code processInstanceId}.
+	 * 
+	 * @param processInstanceId
+	 *            the id of the {@code ProcessInstance} to be deleted.
+	 * @throws EAAFStorageException
+	 *             is thrown if a problem occurs while accessing the database.
+	 */
+	void remove(String processInstanceId) throws EAAFException;
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/Task.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/Task.java
new file mode 100644
index 00000000..ff28b714
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/process/Task.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp.process;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+
+
+/**
+ * Represents a single task to be performed upon process execution.
+ * 
+ * @author tknall
+ * 
+ */
+public interface Task {
+
+	/**
+	 * Executes this task.
+	 * @param pendingReq 
+	 * 			  Provides the current processed protocol request
+	 * @param executionContext
+	 *            Provides execution related information.
+	 * @return The pending-request object, because Process-management works recursive
+	 * @throws Exception An exception upon task execution.
+	 */
+	IRequest execute(IRequest pendingReq, ExecutionContext executionContext) throws TaskExecutionException;
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/slo/ISLOInformationContainer.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/slo/ISLOInformationContainer.java
new file mode 100644
index 00000000..b5798f7b
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/slo/ISLOInformationContainer.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ *******************************************************************************/
+/**
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egiz.eaaf.core.api.idp.slo;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+
+/**
+ * @author tlenz
+ *
+ */
+public interface ISLOInformationContainer {
+
+	boolean hasFrontChannelOA();
+
+	Set<Entry<String, SLOInformationInterface>> getFrontChannelOASessionDescriptions();
+
+	void removeFrontChannelOA(String oaID);
+
+	Iterator<String> getNextBackChannelOA();
+
+	SLOInformationInterface getBackChannelOASessionDescripten(String oaID);
+
+	void removeBackChannelOA(String oaID);
+
+	/**
+	 * @return the sloRequest
+	 */
+	IRequest getSloRequest();
+
+	/**
+	 * @param sloRequest the sloRequest to set
+	 */
+	void setSloRequest(IRequest sloRequest);
+
+	/**
+	 * @return the sloFailedOAs
+	 */
+	List<String> getSloFailedOAs();
+
+	void putFailedOA(String oaID);
+	
+	public String getTransactionID();
+	
+	public String getSessionID();
+}
\ No newline at end of file
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/slo/SLOInformationInterface.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/slo/SLOInformationInterface.java
new file mode 100644
index 00000000..bd630c0a
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/slo/SLOInformationInterface.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ *******************************************************************************/
+/**
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egiz.eaaf.core.api.idp.slo;
+
+/**
+ * @author tlenz
+ *
+ */
+public interface SLOInformationInterface{
+	
+
+	/**
+	 * get AssertionID which was used for Service Provider Single LogOut request 
+	 * 
+	 * @return
+	 * SessionID (SessionIndex in case of SAML2)
+	 */
+	public String getSessionIndex();
+	
+	/**
+	 * get user identifier which was used
+	 * 
+	 * @return
+	 * bPK / wbPK (nameID in case of SAML2)
+	 */
+	public String getUserNameIdentifier();
+	
+	
+	/**
+	 * get protocol type which was used for authentication
+	 * 
+	 * @return
+	 * return authentication protocol type
+	 */
+	public String getProtocolType();
+
+	/**
+	 * @return
+	 */
+	public String getUserNameIDFormat();
+	
+	/**
+	 * Get the unique entityID of this Service-Provider
+	 * 
+	 * @return unique identifier, but never null
+	 */
+	public String getSpEntityID();
+	
+	public String getAuthURL();
+	
+	public String getServiceURL();
+	
+	public String getBinding();
+	
+	public void setUserNameIdentifier(String subjectNameId);
+	
+	public void setNameIDFormat(String format);
+	
+	public void setSessionIndex(String sessionIndex);
+	
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/logging/IRevisionLogger.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/logging/IRevisionLogger.java
new file mode 100644
index 00000000..ab269694
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/logging/IRevisionLogger.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.logging;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+
+public interface IRevisionLogger {
+	
+	
+	//TODO:
+	public static final int AUTHPROTOCOL_TYPE = 3000;
+	
+	void logEvent(ISPConfiguration oaConfig, int eventCode, String message);
+
+	void logEvent(IRequest pendingRequest, int eventCode);
+
+	void logEvent(IRequest pendingRequest, int eventCode, String message);
+
+	/**
+	 * @param sessionCreated
+	 * @param uniqueSessionIdentifier
+	 */
+	void logEvent(int eventCode, String message);
+
+	/**
+	 * @param sessionCreated
+	 * @param uniqueSessionIdentifier
+	 */
+	void logEvent(String sessionID, String transactionID, int eventCode, String message);
+
+	/**
+	 * @param sessionCreated
+	 * @param uniqueSessionIdentifier
+	 */
+	void logEvent(String sessionID, String transactionID, int eventCode);
+
+}
\ No newline at end of file
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/logging/IStatisticLogger.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/logging/IStatisticLogger.java
new file mode 100644
index 00000000..7774fb22
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/logging/IStatisticLogger.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.logging;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+
+
+
+public interface IStatisticLogger {
+		
+	public void logSuccessOperation(IRequest protocolRequest, IAuthData authData, boolean isSSOSession);
+	
+	public void logErrorOperation(Throwable throwable);
+	
+	public void logErrorOperation(Throwable throwable, IRequest errorRequest);
+	
+	public void internalTesting() throws Exception;
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/storage/ITransactionStorage.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/storage/ITransactionStorage.java
new file mode 100644
index 00000000..41c55148
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/storage/ITransactionStorage.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.storage;
+
+import java.util.Date;
+import java.util.List;
+
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException;
+
+/**
+ * @author tlenz
+ *
+ */
+public interface ITransactionStorage {
+
+	/**
+	 * Check if transaction storage contains a data object with a specific key
+	 * 
+	 * @param key Key, which identifies a data object
+	 * @return true if key is found, otherwise false
+	 */
+	public boolean containsKey(String key);
+	
+	/**
+	 * Store a data object with a key to transaction storage
+	 * 
+	 * @param key Id which identifiers the data object
+	 * @param value Data object which should be stored. 
+	 *              This data must implement the <code>java.io.Serializable</code> interface
+	 * @param timeout_ms Defines the period of time a data object is kept within the storage
+	 * @throws EAAFStorageException In case of store operation failed
+	 */
+	public void put(String key, Object value, int timeout_ms) throws EAAFException;
+	
+	/**
+	 * Get a data object from transaction storage
+	 * 
+	 * @param key key Id which identifiers the data object
+	 * @return The transaction-data object, or null
+	 * @throws EAAFStorageException In case of load operation failed
+	 */
+	public Object get(String key) throws EAAFException;
+	
+	/**
+	 * Get a data object from transaction storage
+	 * 
+	 * @param key Id which identifiers the data object
+	 * @param clazz The class type which is stored with this key
+	 * @return The transaction-data object from type class, or null
+	 * @throws EAAFStorageException In case of load operation failed
+	 */
+	public <T> T get(String key, final Class<T> clazz) throws EAAFException;
+	
+	/**
+	 * Get a data object from transaction storage
+	 * 
+	 * @param key Id which identifiers the data object
+	 * @param clazz The class type which is stored with this key
+	 * @param Data-object timeout in [ms]
+	 * @return The transaction-data object from type class, or null
+	 * @throws EAAFStorageException In case of load operation failed
+	 */
+	public <T> T get(String key, final Class<T> clazz, long dataTimeOut) throws EAAFException;
+	
+	
+	/**
+	 * Change the key of a data object and store it under the new key
+	 * 
+	 * @param oldKey Old key of the data object
+	 * @param newKey New key, which should be used to store the data object
+	 * @param value Data object which should be stored
+	 * @throws EAAFStorageException In case of store operation failed
+	 */
+	public void changeKey(String oldKey, String newKey, Object value) throws EAAFException; 
+	
+	/**
+	 * Remove a data object from transaction storage
+	 * 
+	 * @param key Id which identifiers the data object
+	 */
+	public void remove(String key);
+	
+	/**
+	 * Get all entries for Clean-up the transaction storage
+	 * 
+	 * @param now Current time
+	 * @param dataTimeOut Data-object timeout in [ms]
+	 * @return List of entry-keys which as a timeout
+	 */
+	public List<String> clean(Date now, long dataTimeOut);
+	
+	
+	/**
+	 * Get a raw object from storage by using this key
+	 * 
+	 * @param key
+	 * @return
+	 * @throws EAAFException
+	 */
+	public Object getRaw(String key) throws EAAFException;
+	
+	
+	/**
+	 * Set a raw object to storage 
+	 * 
+	 * @param key
+	 * @param element
+	 * @throws EAAFException
+	 */
+	public void putRaw(String key, Object element) throws EAAFException;
+	
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/AttributeBuilderException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/AttributeBuilderException.java
new file mode 100644
index 00000000..7e5373be
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/AttributeBuilderException.java
@@ -0,0 +1,13 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+public class AttributeBuilderException extends EAAFIDPException {
+
+	private static final long serialVersionUID = 1L;
+
+	public AttributeBuilderException(String msg) {
+		super(msg);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/AttributePolicyException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/AttributePolicyException.java
new file mode 100644
index 00000000..7f484feb
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/AttributePolicyException.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+public class AttributePolicyException extends AttributeBuilderException {
+	
+	private static final long serialVersionUID = 1L;
+	
+	private String attributeName;
+	
+	public AttributePolicyException(String attributeName) {
+		super("Attribute " + attributeName + " is restricted by IDP policy.");
+		this.attributeName = attributeName;
+	}
+	
+	public String getAttributeName() {
+		return attributeName;
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/AuthnRequestValidatorException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/AuthnRequestValidatorException.java
new file mode 100644
index 00000000..c416b8e0
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/AuthnRequestValidatorException.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+
+/**
+ * @author tlenz
+ *
+ */
+public class AuthnRequestValidatorException extends EAAFProtocolException {
+
+	private IRequest errorRequest = null;
+	protected String statusCodeValue;
+	
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 4939651000658508576L;
+
+	/**
+	 * @param messageId
+	 * @param parameters
+	 */
+	public AuthnRequestValidatorException(String internalMsgId, Object[] params, String msg) {
+		super(internalMsgId, params, msg);
+		
+	}
+	
+	public AuthnRequestValidatorException(String internalMsgId, Object[] params, String msg, IRequest errorRequest) {
+		super(internalMsgId, params, msg);
+		this.errorRequest = errorRequest;
+		
+	}
+
+	/**
+	 * @return the errorRequest
+	 */
+	public IRequest getErrorRequest() {
+		return errorRequest;
+	}
+
+	public String getStatusCodeValue() {
+		return statusCodeValue;
+	}
+	
+	
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFAuthenticationException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFAuthenticationException.java
new file mode 100644
index 00000000..87176194
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFAuthenticationException.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+public class EAAFAuthenticationException extends EAAFException {
+
+	
+
+	private static final long serialVersionUID = -4793625336456467005L;
+
+	public EAAFAuthenticationException(String internalMsgId, Object[] params, String msg) {
+		super(internalMsgId, params, msg);
+		
+	}
+	
+	public EAAFAuthenticationException(String internalMsgId, Object[] params, String msg, Throwable e) {
+		super(internalMsgId, params, msg, e);
+		
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFBuilderException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFBuilderException.java
new file mode 100644
index 00000000..b58d8b7f
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFBuilderException.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+public class EAAFBuilderException extends EAAFException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	public EAAFBuilderException(String errorId, Object[] params, String msg) {
+		super(errorId, params, msg);
+	}
+
+	public EAAFBuilderException(String errorId, Object[] objects, String message, Exception ex) {
+		super(errorId, objects, message, ex);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFConfigurationException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFConfigurationException.java
new file mode 100644
index 00000000..9615d8fd
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFConfigurationException.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+public class EAAFConfigurationException extends EAAFException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	public EAAFConfigurationException(String msg) {
+		super(msg);
+	}
+
+	public EAAFConfigurationException(String msg, Throwable e) {
+		super(msg, e);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFException.java
new file mode 100644
index 00000000..c72bc130
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFException.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+public class EAAFException extends Exception {
+
+	private static final long serialVersionUID = 1L;
+
+	private String errorId = null;
+	private Object[] params = null;
+
+	public EAAFException(String msg) {
+		super(msg);
+		
+	}
+	
+	public EAAFException(String msg, Throwable e) {
+		super(msg, e);
+		
+	}
+	
+	public EAAFException(String errorId, Object[] params, String msg) {
+		super(msg);
+		this.errorId = errorId;
+		this.params = params;
+		
+	}
+	
+	public EAAFException(String errorId, Object[] params, String msg, Throwable e) {
+		super(msg, e);
+		this.errorId = errorId;
+		this.params = params;
+		
+	}
+	
+	public String getErrorId() {
+		return this.errorId;
+		
+	}
+	
+	public Object[] getParams() {
+		return this.params;
+		
+	}
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFIDPException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFIDPException.java
new file mode 100644
index 00000000..e9cdccb8
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFIDPException.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+public class EAAFIDPException extends EAAFException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	public EAAFIDPException(String msg) {
+		super(msg);
+		
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFIllegalStateException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFIllegalStateException.java
new file mode 100644
index 00000000..65934015
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFIllegalStateException.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+import at.gv.egiz.eaaf.core.api.IStatusMessager;
+
+public class EAAFIllegalStateException extends EAAFException {
+	private static final long serialVersionUID = 261484121729891927L;
+
+	public EAAFIllegalStateException(Object[] params, String msg) {
+		super(IStatusMessager.CODES_INTERNAL_ILLEGAL_STATE, params, msg);
+		
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFParserException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFParserException.java
new file mode 100644
index 00000000..de6e91ae
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFParserException.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+public class EAAFParserException extends EAAFException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	public EAAFParserException(String errorId, Object[] params, String msg) {
+		super(errorId, params, msg);
+	}
+
+	public EAAFParserException(String errorId, Object[] objects, String message, Throwable ex) {
+		super(errorId, objects, message, ex);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFProtocolException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFProtocolException.java
new file mode 100644
index 00000000..f3ed4bb7
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFProtocolException.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+public class EAAFProtocolException extends EAAFException {
+
+	private static final long serialVersionUID = 7982298114399440473L;
+
+	public EAAFProtocolException(String msg) {
+		super(msg);
+
+	}
+	
+	public EAAFProtocolException(String msg, Throwable e) {
+		super(msg, e);
+	}
+
+	public EAAFProtocolException(String errorId, Object[] params, String msg) {
+		super(errorId, params, msg);
+
+	}
+	
+	public EAAFProtocolException(String errorId, Object[] params, String msg, Throwable e) {
+		super(errorId, params, msg, e);
+	}
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFSSOException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFSSOException.java
new file mode 100644
index 00000000..396fee05
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFSSOException.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+public class EAAFSSOException extends EAAFException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -5942886204347860148L;
+
+	public EAAFSSOException(String errorId, Object[] params, String msg, Throwable e) {
+		super(errorId, params, msg, e);
+
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFStorageException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFStorageException.java
new file mode 100644
index 00000000..7d0acef8
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFStorageException.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+public class EAAFStorageException extends EAAFException {
+
+	private static final long serialVersionUID = 1L;
+
+	public EAAFStorageException(String msg) {
+		super(msg);
+	}
+	
+	public EAAFStorageException(String msg, Throwable e) {
+		super(msg, e);
+	}
+	
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/GUIBuildException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/GUIBuildException.java
new file mode 100644
index 00000000..6043d559
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/GUIBuildException.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+/**
+ * @author tlenz
+ *
+ */
+public class GUIBuildException extends Exception {
+
+	private static final long serialVersionUID = -278663750102498205L;
+	
+	/**
+	 * @param string
+	 */
+	public GUIBuildException(String msg) {
+		super(msg);
+		
+	}
+	
+	public GUIBuildException(String msg, Throwable e) {
+		super(msg, e);
+		
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/InvalidDateFormatAttributeException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/InvalidDateFormatAttributeException.java
new file mode 100644
index 00000000..2afc0720
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/InvalidDateFormatAttributeException.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+public class InvalidDateFormatAttributeException extends AttributeBuilderException {
+
+	private static final long serialVersionUID = 1L;
+	
+	public InvalidDateFormatAttributeException() {
+		super("Date format is invalid.");
+	}
+
+	
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/InvalidProtocolRequestException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/InvalidProtocolRequestException.java
new file mode 100644
index 00000000..d7b0933b
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/InvalidProtocolRequestException.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+/**
+ * @author tlenz
+ *
+ */
+public class InvalidProtocolRequestException extends EAAFProtocolException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -7866198705324084601L;
+
+	public InvalidProtocolRequestException(String internalMsgId, Object[] params, String msg) {
+		super(internalMsgId, params, msg);
+	}
+
+	public InvalidProtocolRequestException(String internalMsgId, Object[] params, String msg, Throwable e) {
+		super(internalMsgId, params, msg, e);
+	}
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/NoPassivAuthenticationException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/NoPassivAuthenticationException.java
new file mode 100644
index 00000000..f4d40b6a
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/NoPassivAuthenticationException.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+import at.gv.egiz.eaaf.core.api.IStatusMessager;
+
+public class NoPassivAuthenticationException extends EAAFAuthenticationException {
+
+	public NoPassivAuthenticationException() {
+		super(IStatusMessager.CODES_INTERNAL_ERROR_AUTH_REQUEST_INVALID, null, "");
+	}
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 596920452166197688L;
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/ProcessExecutionException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/ProcessExecutionException.java
new file mode 100644
index 00000000..db678e9b
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/ProcessExecutionException.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+/**
+ * Indicates a problem when executing a process.
+ * 
+ * @author tknall
+ * 
+ */
+public class ProcessExecutionException extends Exception {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Creates a new process execution exception providing a {@code message} describing the reason and the respective
+	 * {@code cause}.
+	 * 
+	 * @param message
+	 *            The message.
+	 * @param cause
+	 *            The cause.
+	 */
+	public ProcessExecutionException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	/**
+	 * Creates a new process execution exception providing a {@code message} describing the reason.
+	 * 
+	 * @param message
+	 *            The message.
+	 */
+	public ProcessExecutionException(String message) {
+		super(message);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/ProtocolNotActiveException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/ProtocolNotActiveException.java
new file mode 100644
index 00000000..33597845
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/ProtocolNotActiveException.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+/**
+ * @author tlenz
+ *
+ */
+public class ProtocolNotActiveException extends EAAFProtocolException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1832697083163940710L;
+
+	public ProtocolNotActiveException(String internalMsgId, Object[] params, String msg) {
+		super(internalMsgId, params, msg);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/SLOException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/SLOException.java
new file mode 100644
index 00000000..66c18db6
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/SLOException.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+/**
+ * @author tlenz
+ *
+ */
+public class SLOException extends EAAFException {
+	private static final long serialVersionUID = -5284624715788385022L;
+
+	/**
+	 * @param messageId
+	 * @param parameters
+	 */
+	public SLOException(String messageId, Object[] parameters) {
+		super(messageId, parameters, "SLO processing error");
+		// TODO Auto-generated constructor stub
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/TaskExecutionException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/TaskExecutionException.java
new file mode 100644
index 00000000..b6c6bd16
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/TaskExecutionException.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+
+/**
+ * @author tlenz
+ *
+ */
+public class TaskExecutionException extends ProcessExecutionException {
+
+	private static final long serialVersionUID = 1L;
+	Throwable originalException = null;
+	String pendingRequestID = null;
+	
+	/**
+	 * @param message
+	 * @param cause
+	 */
+	public TaskExecutionException(IRequest pendingReq, String message, Throwable cause) {
+		super(message, cause);
+		this.originalException = cause;
+		
+		if (StringUtils.isNotEmpty(pendingReq.getPendingRequestId()))
+			this.pendingRequestID = pendingReq.getPendingRequestId();
+		
+	}
+
+	/**
+	 * Get the original internal exception from task
+	 * 
+	 * @return the originalException
+	 */
+	public Throwable getOriginalException() {
+		return originalException;
+		
+	}
+
+	/**
+	 * Get the pending-request ID of that request, which was processed when the exception occurs 
+	 * 
+	 * @return the pendingRequestID
+	 */
+	public String getPendingRequestID() {
+		return pendingRequestID;
+	}
+	
+	
+	
+	
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/UnavailableAttributeException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/UnavailableAttributeException.java
new file mode 100644
index 00000000..f4d5bdae
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/UnavailableAttributeException.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.exceptions;
+
+public class UnavailableAttributeException extends AttributeBuilderException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -1114323185905118432L;
+
+	private String attributeName;
+	
+	public UnavailableAttributeException(String attributeName) {
+		super("Attribute " + attributeName + " is not available.");
+		this.attributeName = attributeName;
+	}
+
+	public String getAttributeName() {
+		return attributeName;
+	}
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/XPathException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/XPathException.java
new file mode 100644
index 00000000..5cccbda4
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/exceptions/XPathException.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ *******************************************************************************/
+
+
+package at.gv.egiz.eaaf.core.exceptions;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * An exception occurred evaluating an XPath.
+ * 
+ */
+public class XPathException extends RuntimeException {
+  /**
+	 * 
+	 */
+	private static final long serialVersionUID = 1736311265333034392L;
+/** The wrapped exception. */
+  private Throwable wrapped;
+  
+  /**
+   * Create a <code>XPathException</code>.
+   * 
+   * @param message The exception message.
+   * @param wrapped The exception being the likely cause of this exception.
+   */
+  public XPathException(String message, Throwable wrapped) {
+    super(message);
+    this.wrapped = wrapped; 
+  }
+  
+  public XPathException(String string) {
+	  super(string);
+}
+
+/**
+   * Return the wrapped exception.
+   * 
+   * @return The wrapped exception being the likely cause of this exception.
+   */
+  public Throwable getWrapped() {
+    return wrapped;
+  }
+
+  /**
+   * @see java.lang.Throwable#printStackTrace(java.io.PrintStream)
+   */
+  public void printStackTrace(PrintStream s) {
+    super.printStackTrace(s);
+    if (getWrapped() != null) {
+      s.print("Caused by: ");
+      getWrapped().printStackTrace(s);
+    }
+  }
+
+  /**
+   * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter)
+   */
+  public void printStackTrace(PrintWriter s) {
+    super.printStackTrace(s);
+    if (getWrapped() != null) {
+      s.print("Caused by: ");
+      getWrapped().printStackTrace(s);
+    }
+  }
+ 
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/Pair.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/Pair.java
new file mode 100644
index 00000000..3277107f
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/Pair.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.data;
+
+public class Pair<P1, P2> {
+	private final P1 first;
+	private final P2 second;
+	
+	private Pair(final P1 newFirst, final P2 newSecond) {
+		this.first = newFirst;
+		this.second = newSecond;
+	}
+	
+	public P1 getFirst() {
+		return this.first;
+	}
+	
+	public P2 getSecond() {
+		return this.second;
+	}
+	
+	public static <P1, P2> Pair<P1, P2> newInstance(final P1 newFirst, final P2 newSecond) {
+		return new Pair<P1, P2>(newFirst, newSecond);
+	}
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/SLOInformationImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/SLOInformationImpl.java
new file mode 100644
index 00000000..46dce216
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/SLOInformationImpl.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.data;
+
+import java.io.Serializable;
+
+import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface;
+
+
+/**
+ * @author tlenz
+ *
+ */
+public class SLOInformationImpl implements SLOInformationInterface, Serializable {
+	
+	private static final long serialVersionUID = 295577931870512387L;
+	private String sessionIndex = null;
+	private String nameID = null;
+	private String protocolType = null;
+	private String nameIDFormat = null;
+	private String binding = null;
+	private String serviceURL = null;
+	private String authURL = null;
+	private String spEntityID = null;
+	
+	public SLOInformationImpl(String authURL, String spEntityID, String sessionID, String nameID, String nameIDFormat, String protocolType) {
+		new SLOInformationImpl(authURL, spEntityID, sessionID, nameID, nameIDFormat, protocolType, null, null);
+	}
+	
+	public SLOInformationImpl(String authURL, String spEntityID, String sessionID, String nameID, String nameIDFormat, String protocolType, String sloBinding, String sloLocationURL) {
+		this.sessionIndex = sessionID;
+		this.nameID = nameID;
+		this.nameIDFormat = nameIDFormat;
+		this.protocolType = protocolType;
+		this.spEntityID = spEntityID;
+		
+		if (authURL.endsWith("/"))
+			this.authURL = authURL.substring(0, authURL.length()-1);
+		else
+			this.authURL = authURL;
+		
+
+		this.binding = sloBinding;
+		this.serviceURL = sloLocationURL;
+							
+	}
+	
+	
+	/**
+	 * 
+	 */
+	public SLOInformationImpl() {
+		
+	}
+
+
+	
+	/**
+	 * @return the spEntityID
+	 */
+	public String getSpEntityID() {
+		return spEntityID;
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.data.SLOInformationInterface#getSessionIndex()
+	 */
+	@Override
+	public String getSessionIndex() {
+		return sessionIndex;
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.data.SLOInformationInterface#getUserNameIdentifier()
+	 */
+	@Override
+	public String getUserNameIdentifier() {
+		return nameID;
+		
+	}
+
+
+	/**
+	 * @param sessionIndex the sessionIndex to set
+	 */
+	public void setSessionIndex(String sessionIndex) {
+		this.sessionIndex = sessionIndex;
+	}
+
+
+	/**
+	 * @param nameID the nameID to set
+	 */
+	public void setUserNameIdentifier(String nameID) {
+		this.nameID = nameID;
+	}
+
+	
+
+	/**
+	 * @param protocolType the protocolType to set
+	 */
+	public void setProtocolType(String protocolType) {
+		this.protocolType = protocolType;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.data.SLOInformationInterface#getProtocolType()
+	 */
+	@Override
+	public String getProtocolType() {
+		return protocolType;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.data.SLOInformationInterface#getUserNameIDFormat()
+	 */
+	@Override
+	public String getUserNameIDFormat() {
+		return this.nameIDFormat;
+	}
+
+
+	/**
+	 * @param nameIDFormat the nameIDFormat to set
+	 */
+	public void setNameIDFormat(String nameIDFormat) {
+		this.nameIDFormat = nameIDFormat;
+	}
+
+	/**
+	 * @return the binding
+	 */
+	public String getBinding() {
+		return binding;
+	}
+
+	/**
+	 * @return the serviceURL
+	 */
+	public String getServiceURL() {
+		return serviceURL;
+	}
+
+	/**
+	 * @return the authURL from requested IDP without ending /
+	 */
+	public String getAuthURL() {
+		return authURL;
+	}
+
+	/**
+	 * @param spEntityID the spEntityID to set
+	 */
+	public void setSpEntityID(String spEntityID) {
+		this.spEntityID = spEntityID;
+	}
+	
+	
+	
+	
+	
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/Trible.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/Trible.java
new file mode 100644
index 00000000..b817de42
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/Trible.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.data;
+
+public class Trible<P1, P2, P3> {
+	private final P1 first;
+	private final P2 second;
+	private final P3 third;
+	
+	private Trible(final P1 newFirst, final P2 newSecond, final P3 newThird) {
+		this.first = newFirst;
+		this.second = newSecond;
+		this.third = newThird;
+	}
+	
+	public P1 getFirst() {
+		return this.first;
+	}
+	
+	public P2 getSecond() {
+		return this.second;
+	}
+	
+	public P3 getThird() {
+		return this.third;
+	}
+	
+	public static <P1, P2, P3> Trible<P1, P2, P3> newInstance(final P1 newFirst, final P2 newSecond, final P3 newThird) {
+		return new Trible<P1, P2, P3>(newFirst, newSecond, newThird);
+	}
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/AbstractGUIFormBuilderConfiguration.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/AbstractGUIFormBuilderConfiguration.java
new file mode 100644
index 00000000..0ab13a9b
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/AbstractGUIFormBuilderConfiguration.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.gui;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfiguration;
+
+/**
+ * @author tlenz
+ *
+ */
+public abstract class AbstractGUIFormBuilderConfiguration implements IGUIBuilderConfiguration {
+
+	public static final String PARAM_AUTHCONTEXT = "contextPath";
+	public static final String PARAM_FORMSUBMITENDPOINT = "submitEndpoint";	
+	public static final String PARAM_PENDINGREQUESTID = "pendingReqID";
+	
+	private String authURL = null;
+	private String viewName = null;
+	private String formSubmitEndpoint = null;
+	
+	/**
+	 * @param authURL IDP PublicURL-Prefix which should be used, but never null
+	 * @param viewName Name of the template (with suffix) but never null
+	 * @param formSubmitEndpoint EndPoint on which the form should be submitted, 
+	 * or null if the form must not submitted
+	 * 
+	 */
+	public AbstractGUIFormBuilderConfiguration(String authURL, String viewName, String formSubmitEndpoint) {
+		if (viewName.startsWith("/"))
+			this.viewName = viewName.substring(1);
+		else
+			this.viewName = viewName;
+		
+		if (authURL.endsWith("/"))
+			this.authURL = authURL.substring(0, authURL.length() - 1);
+		else
+			this.authURL = authURL;
+		
+		if (StringUtils.isNotEmpty(formSubmitEndpoint)) {
+			if (formSubmitEndpoint.startsWith("/"))
+				this.formSubmitEndpoint = formSubmitEndpoint;
+			else		
+				this.formSubmitEndpoint = "/" + formSubmitEndpoint;
+		}
+	}
+	
+	
+	/**
+	 * Define the parameters, which should be evaluated in the template <br>
+	 * <b>IMPORTANT:</b> external HTML escapetion is required, because it is NOT done internally during the building process
+	 * 
+	 * @return Map of parameters, which should be added to template
+	 */
+	abstract protected Map<String, Object> getSpecificViewParameters();
+		
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.frontend.builder.IGUIBuilderConfiguration#getViewName()
+	 */
+	@Override
+	public final String getViewName() {
+		return this.viewName;
+		
+	}
+	
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.frontend.builder.IGUIBuilderConfiguration#getViewParameters()
+	 */
+	@Override
+	public final Map<String, Object> getViewParameters() {
+		//get parameters from detail implementation
+		Map<String, Object> specParams = getSpecificViewParameters();
+		if (specParams == null)
+			specParams = new HashMap<String, Object>();
+		
+		//add generic parameters
+		specParams.put(PARAM_AUTHCONTEXT, this.authURL);		
+		if (this.formSubmitEndpoint != null)
+			specParams.put(PARAM_FORMSUBMITENDPOINT, this.formSubmitEndpoint);
+		
+		return specParams;
+		
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/AbstractGUIFormBuilderImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/AbstractGUIFormBuilderImpl.java
new file mode 100644
index 00000000..a71fc21e
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/AbstractGUIFormBuilderImpl.java
@@ -0,0 +1,192 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.gui;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfiguration;
+import at.gv.egiz.eaaf.core.api.gui.IGUIFormBuilder;
+import at.gv.egiz.eaaf.core.exceptions.GUIBuildException;
+import at.gv.egiz.eaaf.core.impl.gui.velocity.VelocityProvider;
+
+/**
+ * @author tlenz 
+ *
+ */
+public abstract class AbstractGUIFormBuilderImpl implements IGUIFormBuilder {
+	private static final Logger log = LoggerFactory.getLogger(AbstractGUIFormBuilderImpl.class);
+	private static final String DEFAULT_CONTENT_TYPE = EAAFConstants.CONTENTTYPE_HTML_UTF8;
+			
+	private VelocityEngine engine;
+		
+	public AbstractGUIFormBuilderImpl() throws GUIBuildException {
+		try {
+			engine = VelocityProvider.getClassPathVelocityEngine();
+			
+		} catch (Exception e) {
+			log.error("Initialization of Velocity-Engine to render GUI components FAILED.", e);
+			throw new GUIBuildException("Initialization of Velocity-Engine to render GUI components FAILED.", e);
+			
+		}
+		
+	}
+		
+	public void build(HttpServletResponse httpResp, IGUIBuilderConfiguration config, String loggerName) throws GUIBuildException {
+		build(httpResp, config, getInternalContentType(config), loggerName);
+		
+	}
+		
+	@Override
+	public void build(HttpServletResponse httpResp, IGUIBuilderConfiguration config, 
+			String contentType, String loggerName) throws GUIBuildException {
+		
+		InputStream is = null;
+		try {
+			String viewName = config.getViewName();			
+			is = getTemplateInputStream(config);
+			
+			//build Velocity Context from input paramters
+			VelocityContext context = buildContextFromViewParams(config.getViewParameters());
+
+			//evaluate template
+			StringWriter writer = new StringWriter();
+			engine.evaluate(context, writer, loggerName, new BufferedReader(new InputStreamReader(is)));
+							
+			//write template to response
+			final byte[] content = writer.toString().getBytes("UTF-8");
+			httpResp.setStatus(HttpServletResponse.SC_OK);
+			httpResp.setContentLength(content.length);
+			httpResp.setContentType(contentType);						
+			httpResp.getOutputStream().write(content);
+			
+			if (log.isTraceEnabled()) {
+				log.trace("Write Content for viewName:" + viewName 
+						+ ". Contentsize:" + String.valueOf(content.length)
+						+ " BufferSize:" + httpResp.getBufferSize()
+						+ " ContentType:" + contentType);
+				for (String el : httpResp.getHeaderNames())
+					log.trace(" * Headername:" + el + " Value:" + httpResp.getHeader(el));
+				
+			}
+			
+		} catch (IOException e) {
+			log.error("GUI form-builder has an internal error.", e);
+			throw new GUIBuildException("GUI form-builder has an internal error.", e);
+						
+		} finally {
+			if (is != null)
+				try {
+					is.close();
+					
+				} catch (IOException e) {
+					log.error("Can NOT close GUI-Template InputStream.", e);
+					
+				}
+		}
+		
+	}
+
+	/**
+	 * Generate a new {@link VelocityContext} and populate it with MOA-ID GUI parameters
+	 * 
+	 * @param config
+	 * @return
+	 */
+	public VelocityContext generateVelocityContextFromConfiguration(IGUIBuilderConfiguration config) {
+		return buildContextFromViewParams(config.getViewParameters());
+		
+	}
+	
+	/**
+	 * Load the template from different resources
+	 * 
+	 * @param config
+	 * @return An {@link InputStream} but never null. The {@link InputStream} had to be closed be the invoking method
+	 * @throws GUIBuildException
+	 */
+	public InputStream getTemplateInputStream(IGUIBuilderConfiguration config) throws GUIBuildException {
+		InputStream is = config.getTemplate(config.getViewName());
+		if (is == null) {
+			log.trace("Loading GUI template:" + config.getViewName() + " from default resources ... ");
+			is = getInternalTemplate(config);
+			
+			if (is == null) {
+				log.warn("No GUI with viewName:" + config.getViewName() + " FOUND.");
+				throw new GUIBuildException("No GUI with viewName:" + config.getViewName() + " FOUND.");
+		
+			}
+		}		
+		return is;
+		
+	}
+	
+	/**
+	 * Load an internal template from default resources
+	 * 
+	 * @param config
+	 * @return
+	 * @throws GUIBuildException
+	 */
+	abstract protected InputStream getInternalTemplate(IGUIBuilderConfiguration config) throws GUIBuildException;
+
+	
+	/**
+	 * @return
+	 */ 
+	protected String getInternalClasspathTemplateDir(IGUIBuilderConfiguration config, String defaultClassPathDir) {
+		String dir = config.getClasspathTemplateDir();
+		if (dir != null) {
+			if (!dir.endsWith("/"))
+				dir += "/";
+			
+			return dir;			
+			
+		} else
+			return defaultClassPathDir;
+	}
+	
+	/**
+	 * @param viewParams
+	 * @return
+	 */
+	private VelocityContext buildContextFromViewParams(Map<String, Object> viewParams) {
+		VelocityContext context = new VelocityContext();
+				
+		if (viewParams != null) {
+			Iterator<Entry<String, Object>> interator = viewParams.entrySet().iterator();
+			while (interator.hasNext()) {
+				Entry<String, Object> el = interator.next();
+				context.put(el.getKey(), el.getValue());
+			}
+			
+		} 
+		
+		return context;
+	}
+	
+	private String getInternalContentType(IGUIBuilderConfiguration config) {
+		if (StringUtils.isEmpty(config.getDefaultContentType()))
+			return DEFAULT_CONTENT_TYPE;
+		
+		else
+			return config.getDefaultContentType();
+		
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/velocity/VelocityLogAdapter.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/velocity/VelocityLogAdapter.java
new file mode 100644
index 00000000..51a59a8e
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/velocity/VelocityLogAdapter.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.gui.velocity;
+
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.runtime.RuntimeServices;
+import org.apache.velocity.runtime.log.LogChute;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VelocityLogAdapter implements LogChute {
+
+	private static final Logger log = LoggerFactory.getLogger(VelocityLogAdapter.class);
+	
+	public VelocityLogAdapter() {
+		try
+	    {
+	      /*
+	       *  register this class as a logger with the Velocity singleton
+	       *  (NOTE: this would not work for the non-singleton method.)
+	       */
+	      Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, this );
+	      Velocity.init();
+	    }
+	    catch (Exception e)
+	    {
+	    	 log.error("Failed to register Velocity logger");
+	    }
+	}
+	
+	public void init(RuntimeServices arg0) throws Exception {
+	}
+
+	public boolean isLevelEnabled(int arg0) {
+		switch(arg0) {
+		case LogChute.DEBUG_ID:
+			return  log.isDebugEnabled();
+		case LogChute.TRACE_ID:
+			return  log.isTraceEnabled();
+		default:
+			return true;
+		}
+	}
+
+	public void log(int arg0, String arg1) {
+		switch(arg0) {
+		case LogChute.DEBUG_ID:
+			 log.debug(arg1);
+			break;
+		case LogChute.TRACE_ID:
+			 log.trace(arg1);
+			break;
+		case LogChute.INFO_ID:
+			 log.info(arg1);
+			break;
+		case LogChute.WARN_ID:
+			 log.warn(arg1);
+			break;
+		case LogChute.ERROR_ID:
+		default:
+			 log.error(arg1);
+			break;
+		}
+	}
+
+	public void log(int arg0, String arg1, Throwable arg2) {
+		switch(arg0) {
+		case LogChute.DEBUG_ID:
+		case LogChute.TRACE_ID:
+		case LogChute.INFO_ID:
+		case LogChute.WARN_ID:
+			 log.warn(arg1, arg2);
+			break;
+		case LogChute.ERROR_ID:
+		default:
+			 log.error(arg1, arg2);
+			break;
+		}
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/velocity/VelocityProvider.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/velocity/VelocityProvider.java
new file mode 100644
index 00000000..5775e203
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/velocity/VelocityProvider.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/*
+ * Copyright 2011 by Graz University of Technology, Austria
+ * The Austrian STORK Modules have been developed by the E-Government
+ * Innovation Center EGIZ, a joint initiative of the Federal Chancellery
+ * Austria and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+/**
+ * 
+ */
+package at.gv.egiz.eaaf.core.impl.gui.velocity;
+
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+
+/**
+ * Gets a Velocity Engine
+ * 
+ * @author bzwattendorfer
+ *
+ */
+public class VelocityProvider {
+
+	private static VelocityEngine velocityEngine = null;
+	
+	/**
+	 * Gets velocityEngine from Classpath
+	 * @return VelocityEngine
+	 * @throws Exception
+	 */
+	public static VelocityEngine getClassPathVelocityEngine() throws Exception {
+		if (velocityEngine == null) {
+			velocityEngine = getBaseVelocityEngine();
+			velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
+			velocityEngine.setProperty("classpath.resource.loader.class",
+					"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");                
+			velocityEngine.init();
+			
+		}
+		
+		return velocityEngine;
+	}
+	
+	/**
+	 * Gets VelocityEngine from File
+	 * @param rootPath File Path to template file
+	 * @return VelocityEngine
+	 * @throws Exception
+	 */
+	public static VelocityEngine getFileVelocityEngine(String rootPath) throws Exception {
+		if (velocityEngine == null) {
+			velocityEngine = getBaseVelocityEngine();
+			velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "file");
+			velocityEngine.setProperty("file.resource.loader.class",
+					"org.apache.velocity.runtime.resource.loader.FileResourceLoader");
+			velocityEngine.setProperty("file.resource.loader.path", rootPath);
+        
+			velocityEngine.init();
+			
+		}
+		
+		return velocityEngine;
+	}
+	
+	/**
+	 * Gets a basic VelocityEngine
+	 * @return VelocityEngine
+	 */
+	private static VelocityEngine getBaseVelocityEngine() {
+		VelocityEngine velocityEngine = new VelocityEngine();
+        velocityEngine.setProperty(RuntimeConstants.INPUT_ENCODING, "UTF-8");
+        velocityEngine.setProperty(RuntimeConstants.OUTPUT_ENCODING, "UTF-8");
+//        velocityEngine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
+//				"org.apache.velocity.runtime.log.SimpleLog4JLogSystem");
+        velocityEngine.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, new VelocityLogAdapter() );
+        
+        return velocityEngine;
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/AuthenticationData.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/AuthenticationData.java
new file mode 100644
index 00000000..f35a54fa
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/AuthenticationData.java
@@ -0,0 +1,416 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp;
+
+import java.io.Serializable;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.apache.commons.collections4.map.HashedMap;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
+import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException;
+
+/**
+ * @author tlenz
+ *
+ */
+public class AuthenticationData  implements IAuthData, Serializable {
+
+	private static final Logger log = LoggerFactory.getLogger(AuthenticationData.class);
+	
+	private static final long serialVersionUID = -1042697056735596866L;
+	public static final String IDENTITY_LINK_DATE_FORMAT = "yyyy-MM-dd";
+
+	private boolean isBaseIDTransferRestrication = true;
+	private Map<String, Object> genericDataStorate = new HashedMap<String, Object>();
+	
+	private String issuer;
+	private Date issueInstant;
+	  
+	private String identificationValue;
+	private String identificationType;
+	private IIdentityLink identityLink = null;
+	
+	private String familyName;
+	private String givenName;
+	private Date dateOfBirth;
+	private String bPK;	 
+	private String bPKType;
+	
+	private String ccc = null;
+	  
+	  	  
+	private boolean foreigner =false;
+	private String eIDASLoA = null;
+	  
+    private boolean ssoSession = false;
+	private Date ssoSessionValidTo = null;
+  
+	private String sessionIndex = null;
+	private String nameID = null;
+	private String nameIDFormat = null;
+	  
+	public AuthenticationData() {
+		  this.issueInstant = new Date();
+		  
+	}
+
+	@Override
+	public String getAuthenticationIssuer() {
+		return this.issuer;
+	}
+
+	/**
+	 * Set an unique identifier for the IDP that authenticates the user
+	 * 
+	 * @param authIssuer
+	 */
+	public void setAuthenticationIssuer(String authIssuer) {
+		this.issuer = authIssuer;
+		
+	}
+	
+
+	@Override
+	public Date getAuthenticationIssueInstant() {
+		return this.issueInstant;
+	}
+
+
+    public String getAuthenticationIssueInstantString() {    	 
+  	  SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+  	  f.setTimeZone(TimeZone.getTimeZone("UTC"));
+  	  return f.format(this.issueInstant);
+	    
+	}
+	
+    /**
+     * Set the timestamp for this user authentication process
+     * 
+     * @param date
+     */
+	public void setAuthenticationIssueInstant(Date date) {
+		  this.issueInstant = date;
+	}
+    
+	@Override
+	public String getCiticenCountryCode() {
+		return this.ccc;
+	}
+	
+
+	public String getBPK() {
+	    return bPK;
+	}
+
+	/**
+	 * Sets the bPK.
+	 * @param bPK The bPK to set
+	 */
+	public void setBPK(String bPK) {
+		this.bPK = bPK;
+	}
+
+
+	public Date getDateOfBirth() {
+	    return this.dateOfBirth;
+	}
+
+	public String getFormatedDateOfBirth() {
+		DateFormat pvpDateFormat = new SimpleDateFormat(IDENTITY_LINK_DATE_FORMAT);
+		if (getDateOfBirth() != null)
+			return pvpDateFormat.format(getDateOfBirth());
+		else
+			return "2999-12-31";
+		
+	}
+	  
+
+	public String getFamilyName() {
+	    return this.familyName;
+	}
+
+
+	public String getGivenName() {
+		return this.givenName;
+	}
+
+
+	public String getIdentificationValue() {
+	    return identificationValue;
+	}
+
+
+	public String getIdentificationType() {
+		return identificationType;
+	}
+
+	@Override
+	public IIdentityLink getIdentityLink() {
+		return identityLink;
+	}
+
+	/**
+	 * @param identityLink the identityLink to set
+	 */
+	public void setIdentityLink(IIdentityLink identityLink) {
+		this.identityLink = identityLink;
+	}  	  	
+	
+	/**
+	 * Sets the dateOfBirth.
+	 * @param dateOfBirth The dateOfBirth to set
+	 */
+	public void setDateOfBirth(Date dateOfBirth) {
+	    this.dateOfBirth = dateOfBirth;
+	}
+
+	public void setDateOfBirth(String dateOfBirth) {		  
+		try {		  
+			if (StringUtils.isNotEmpty(dateOfBirth)) {
+				DateFormat identityLinkFormat = new SimpleDateFormat(IDENTITY_LINK_DATE_FORMAT);
+				this.dateOfBirth = identityLinkFormat.parse(dateOfBirth);
+		
+			}
+			  
+		} catch (ParseException e) {
+			log.warn("Parse dateOfBirht from IdentityLink FAILED", e);
+			  
+		}		  
+	 }
+	  
+	/**
+	 * Sets the familyName.
+	 * @param familyName The familyName to set
+	 */
+	public void setFamilyName(String familyName) {
+	    this.familyName = familyName;
+	}
+
+	/**
+	 * Sets the givenName.
+	 * @param givenName The givenName to set
+	 */
+	public void setGivenName(String givenName) {
+	    this.givenName = givenName;
+	}
+
+	/**
+	 * Sets the identificationValue.
+	 * @param identificationValue The identificationValue to set
+	 */
+	public void setIdentificationValue(String identificationValue) {
+	    this.identificationValue = identificationValue;
+	}
+
+	/**
+	 * Sets the identificationType.
+	 * @param identificationType The identificationType to set
+	 */
+	public void setIdentificationType(String identificationType) {
+		this.identificationType = identificationType;
+	}
+
+
+	public String getBPKType() {
+		return bPKType;
+	}
+
+	/**
+	 * Set sector identifier of user's bPK
+	 * 
+	 * @param bPKType
+	 */
+	public void setBPKType(String bPKType) {
+		this.bPKType = bPKType;
+	}
+	
+	public String getEIDASQAALevel() {
+		return this.eIDASLoA;
+		
+	}
+	
+
+	public boolean isForeigner() {
+		return this.foreigner;
+	}
+
+
+	/**
+	 * Indicate the the user is a foreigner
+	 * 
+	 * @param true if the user is a foreigner, otherwise false
+	 */
+	public void setForeigner(boolean foreigner) {
+		this.foreigner = foreigner;
+	}
+
+	@Override
+	public boolean isSsoSession() {
+		return ssoSession;
+	}
+
+
+	/**
+	 * Indicate that the authentication was done by using an active SSO session
+	 * 
+	 * @param true if a SSO was used, otherwise false
+	 */
+	public void setSsoSession(boolean ssoSession) {
+		this.ssoSession = ssoSession;
+	}
+
+
+	/**
+	 * Country Code for the authenticated user
+	 * 
+	 * @param ccc Two letter country code
+	 */
+	public void setCiticenCountryCode(String ccc) {
+		this.ccc = ccc;
+	}
+
+	public String getSessionIndex() {
+		return sessionIndex;
+	}
+
+	/**
+	 * @param sessionIndex the sessionIndex to set
+	 */
+	public void setSessionIndex(String sessionIndex) {
+		this.sessionIndex = sessionIndex;
+	}
+
+
+	@Override
+	public String getNameID() {
+		return this.nameID;
+	}
+
+	/**
+	 * @param nameID the nameID to set
+	 */
+	public void setNameID(String nameID) {
+		this.nameID = nameID;
+	}
+
+	/**
+	 * @return the nameIDFormat
+	 */
+	public String getNameIDFormat() {
+		return nameIDFormat;
+	}
+
+	/**
+	 * @param nameIDFormat the nameIDFormat to set
+	 */
+	public void setNameIDFormat(String nameIDFormat) {
+		this.nameIDFormat = nameIDFormat;
+	}
+
+	/**
+	 * @return the ssoSessionValidTo
+	 */
+	public Date getSsoSessionValidTo() {
+		return ssoSessionValidTo;
+	}
+
+	/**
+	 * @param ssoSessionValidTo the ssoSessionValidTo to set
+	 */
+	public void setSsoSessionValidTo(Date ssoSessionValidTo) {
+		this.ssoSessionValidTo = ssoSessionValidTo;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.data.IAuthData#isBusinessService()
+	 */
+	@Override
+	public boolean isBaseIDTransferRestrication() {
+		return isBaseIDTransferRestrication;
+	}
+
+	/**
+	 * @param isBaseIDTransmittionAllowed the isBaseIDTransmittionAllowed to set
+	 */
+	public void setBaseIDTransferRestrication(boolean isBaseIDTransferRestrication) {
+		this.isBaseIDTransferRestrication = isBaseIDTransferRestrication;
+	}
+	
+	/**
+	 * Returns a generic data-object with is stored with a specific identifier 
+	 * 
+	 * @param key The specific identifier of the data object
+	 * @param clazz The class type which is stored with this key
+	 * @return The data object or null if no data is found with this key
+	 */
+	public <T> T getGenericData(String key, final Class<T> clazz) {
+		if (StringUtils.isNotEmpty(key)) {
+			Object data = genericDataStorate.get(key);			
+			
+			if (data == null)
+				return null;
+			
+			try {
+				@SuppressWarnings("unchecked")
+				T test = (T) data;
+				return test;
+				
+			} catch (Exception e) {
+				log.warn("Generic authentication-data object can not be casted to requsted type", e);
+				return null;
+				
+			}
+			
+		} 
+		
+		log.info("Can not load generic session-data with key='null'");
+		return null;
+				
+	}
+	
+	/**
+	 * Store a generic data-object to session with a specific identifier
+	 * 
+	 * @param key Identifier for this data-object
+	 * @param object Generic data-object which should be stored. This data-object had to be implement the 'java.io.Serializable' interface
+	 * @throws SessionDataStorageException Error message if the data-object can not stored to generic session-data storage
+	 */
+	public void setGenericData(String key, Object object) throws EAAFStorageException {
+		if (StringUtils.isEmpty(key)) {
+			log.info("Generic session-data can not be stored with a 'null' key");
+			throw new EAAFStorageException("Generic data can not be stored with a 'null' key", null);
+			
+		}
+		
+		if (object != null) {
+			if (!Serializable.class.isInstance(object)) {
+				log.warn("Generic data can only store objects which implements the 'Seralizable' interface");
+				throw new EAAFStorageException("Generic data can only store objects which implements the 'Seralizable' interface", null);
+				
+			}						
+		}
+		
+		if (genericDataStorate.containsKey(key))
+			log.debug("Overwrite generic data with key:" + key);
+		else
+			log.trace("Add generic data with key:" + key + " to session.");
+		
+		genericDataStorate.put(key, object);
+	}
+
+	public void seteIDASLoA(String eIDASLoA) {
+		this.eIDASLoA = eIDASLoA;
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/EAAFCoreSpringResourceProvider.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/EAAFCoreSpringResourceProvider.java
new file mode 100644
index 00000000..a289f49d
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/EAAFCoreSpringResourceProvider.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp;
+
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import at.gv.egiz.components.spring.api.SpringResourceProvider;
+
+public class EAAFCoreSpringResourceProvider implements SpringResourceProvider {
+
+	@Override
+	public String getName() {
+		return "EAAF Core SpringResourceProvider";
+	}
+
+	@Override
+	public String[] getPackagesToScan() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Resource[] getResourcesToLoad() {
+		ClassPathResource sl20AuthConfig = new ClassPathResource("/eaaf_core.beans.xml", EAAFCoreSpringResourceProvider.class);					
+		
+		return new Resource[] {sl20AuthConfig};
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java
new file mode 100644
index 00000000..e52a7884
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java
@@ -0,0 +1,341 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.auth;
+
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IRequestStorage;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.auth.IAuthenticationManager;
+import at.gv.egiz.eaaf.core.api.idp.auth.ISSOManager;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
+import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFSSOException;
+import at.gv.egiz.eaaf.core.exceptions.NoPassivAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.ProcessExecutionException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.idp.auth.modules.ModuleRegistration;
+import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
+import at.gv.egiz.eaaf.core.impl.idp.process.ExecutionContextImpl;
+import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils;
+
+public abstract class AbstractAuthenticationManager implements IAuthenticationManager {
+	private static final Logger log = LoggerFactory.getLogger(AbstractAuthenticationManager.class);
+	
+	private static List<String> reqParameterWhiteListeForModules = new ArrayList<String>();
+	private static List<String> reqHeaderWhiteListeForModules = new ArrayList<String>();
+	
+	public static final String MOA_SESSION = "MoaAuthenticationSession";
+	public static final String MOA_AUTHENTICATED = "MoaAuthenticated";
+
+	public static final int SLOTIMEOUT = 30 * 1000; //30 sec
+	
+	@Autowired(required=true) protected IConfiguration authConfig;
+	@Autowired(required=true) private ProcessEngine processEngine;	
+	@Autowired(required=true) private IRequestStorage requestStoreage;	
+	@Autowired(required=true) protected IRevisionLogger revisionsLogger;	
+	@Autowired(required=false) protected ISSOManager ssoManager;
+	
+	/* (non-Javadoc)
+	 * @see at.gv.egiz.eaaf.core.impl.idp.auth.IAuthenticationManager#addParameterNameToWhiteList(java.lang.String)
+	 */
+	@Override
+	public final void addParameterNameToWhiteList(String httpReqParam) {
+		if (StringUtils.isNotEmpty(httpReqParam))
+			reqParameterWhiteListeForModules.add(httpReqParam);
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see at.gv.egiz.eaaf.core.impl.idp.auth.IAuthenticationManager#addHeaderNameToWhiteList(java.lang.String)
+	 */
+	@Override
+	public final void addHeaderNameToWhiteList(String httpReqParam) {
+		if (StringUtils.isNotEmpty(httpReqParam))
+			reqHeaderWhiteListeForModules.add(httpReqParam.toLowerCase());
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egiz.eaaf.core.impl.idp.auth.IAuthenticationManager#addHeaderNameToWhiteList(java.lang.String)
+	 */
+	@Override
+	public final boolean doAuthentication(HttpServletRequest httpReq, HttpServletResponse httpResp,
+			IRequest pendingReq) throws EAAFException {
+	
+		if (!(pendingReq instanceof RequestImpl)) {
+			log.error("Requests that need authentication MUST be of type 'RequestImpl'");
+			throw new RuntimeException("Requests that need authentication HAS TO BE of type 'RequestImpl'");
+			
+		}
+		
+		//load OA configuration from pending request
+		ISPConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
+				
+		//set logging context and log unique OA identifier to revision log 
+		TransactionIDUtils.setServiceProviderId(oaParam.getUniqueIdentifier());
+		revisionsLogger.logEvent(pendingReq, EVENT_AUTHENTICATION_PROCESS_FOR_SP, pendingReq.getSPEntityId());
+						
+		//generic authentication request validation 
+		if (pendingReq.isPassiv() && pendingReq.forceAuth()) {
+			// conflict!
+			throw new NoPassivAuthenticationException();
+		}
+				
+		
+		//check Single Sign-On functionality if SSOManager is available
+		boolean isValidSSOSession = false; 
+		if (ssoManager != null) {
+			log.trace("SSOManager is loaded. Starting SSO session validation ... ");
+			//check if SSO is allowed for this service provider
+			ssoManager.isSSOAllowedForSP(pendingReq, httpReq);
+	
+			//check if SSO session is active and valid
+			isValidSSOSession = ssoManager.checkAndValidateSSOSession(pendingReq, httpReq, httpResp);
+						
+		}
+				
+		//check if session is already authenticated
+		//boolean isSessionAuthenticated = tryPerformAuthentication((RequestImpl) pendingReq, isValidSSOSession);
+		//boolean isSessionAuthenticated = isValidSSOSession && StringUtils.isNotEmpty(pendingReq.getSSOSessionIdentifier());
+		
+		
+		//force new authentication authentication process
+		if (pendingReq.forceAuth()) {	
+			startAuthenticationProcess(httpReq, httpResp, (RequestImpl) pendingReq);
+			return false;
+				
+		//perform SSO-Consents evaluation if it it required			
+		} else if (isValidSSOSession && pendingReq.isNeedUserConsent()) {						
+			sendSingleSignOnConsentsEvaluation(httpReq, httpResp, (RequestImpl) pendingReq);
+			return false;
+		
+			
+		} else if (pendingReq.isPassiv()) {
+			if (isValidSSOSession && 
+					StringUtils.isNotEmpty(pendingReq.getSSOSessionIdentifier()) ) {
+				// Passive authentication ok! --> Populate pending request from SSO session
+				ssoManager.populatePendingRequestWithSSOInformation(pendingReq);				
+				revisionsLogger.logEvent(pendingReq, EVENT_AUTHENTICATION_PROCESS_FINISHED);
+				return true;
+				
+			} else {				
+				throw new NoPassivAuthenticationException();
+				
+			}
+			
+		} else {
+			if (isValidSSOSession  && 
+					StringUtils.isNotEmpty(pendingReq.getSSOSessionIdentifier())) {
+				// Is authenticated .. proceed
+				ssoManager.populatePendingRequestWithSSOInformation(pendingReq);
+				revisionsLogger.logEvent(pendingReq, EVENT_AUTHENTICATION_PROCESS_FINISHED);
+				return true;
+				
+			} else {
+				// Start authentication!
+				startAuthenticationProcess(httpReq, httpResp, (RequestImpl) pendingReq);
+				return false;
+				
+			}
+		}		
+	}
+
+	public final void performOnlyIDPLogOut(HttpServletRequest request, HttpServletResponse response, IRequest pendingReq) {		
+		
+		log.debug("Close session. Remove pending request ... ");
+		requestStoreage.removePendingRequest(pendingReq.getPendingRequestId());
+		
+		
+		if (ssoManager != null) {
+			try {
+				log.trace("'SSOManager' active. Search for active SSO sessions ...  ");						
+				if (ssoManager.destroySSOSessionOnIDPOnly(request, response, pendingReq))
+					log.info("SSO session successfully closed");
+				else
+					log.info("Closing SSO session NOT successfully");
+				
+			} catch (EAAFSSOException e) {
+				log.warn("Destroying of SSO session FAILED. Reason: " + e.getMessage(), e);
+				
+			}
+						
+		}
+		
+	}
+	
+	/**
+	 * Populate process execution context and start process engine
+	 * 
+	 * @param httpReq
+	 * @param httpResp
+	 * @param pendingReq
+	 * @throws ServletException
+	 * @throws IOException
+	 * @throws EAAFException
+	 */
+	private void startAuthenticationProcess(HttpServletRequest httpReq,
+			HttpServletResponse httpResp, RequestImpl pendingReq)
+			throws EAAFException {
+				
+		log.info("Starting authentication ...");		
+		revisionsLogger.logEvent(pendingReq, EVENT_AUTHENTICATION_PROCESS_STARTED);
+
+		//create authentication process execution context
+		ExecutionContext executionContext = new ExecutionContextImpl();
+		
+		//set oaIdentifeir
+		executionContext.put(EAAFConstants.PROCESS_ENGINE_SERVICE_PROVIDER_ENTITYID, 
+				pendingReq.getServiceProviderConfiguration().getUniqueIdentifier());		
+		
+		//add X509 SSL client certificate if exist
+		if (httpReq.getAttribute("javax.servlet.request.X509Certificate") != null) {
+			log.debug("Find SSL-client-certificate on request --> Add it to context");
+			executionContext.put(EAAFConstants.PROCESS_ENGINE_SSL_CLIENT_CERTIFICATE, 
+					((X509Certificate[])httpReq.getAttribute("javax.servlet.request.X509Certificate")));
+			pendingReq.setGenericDataToSession(EAAFConstants.PROCESS_ENGINE_SSL_CLIENT_CERTIFICATE, 
+					((X509Certificate[])httpReq.getAttribute("javax.servlet.request.X509Certificate")));
+			
+		}
+				
+		//add additional http request parameter to context
+		if (!reqParameterWhiteListeForModules.isEmpty()) {
+			Enumeration<String> reqParamNames = httpReq.getParameterNames();
+			while(reqParamNames.hasMoreElements()) {
+				String paramName = reqParamNames.nextElement();
+				if (StringUtils.isNotEmpty(paramName) &&  reqParameterWhiteListeForModules.contains(paramName) )
+					executionContext.put(paramName, StringEscapeUtils.escapeHtml4(httpReq.getParameter(paramName)));				
+			}			
+		}
+		
+		//add additional http request parameter to context
+		if (!reqHeaderWhiteListeForModules.isEmpty()) {
+			Enumeration<String> reqHeaderNames = httpReq.getHeaderNames();
+			while(reqHeaderNames.hasMoreElements()) { 
+				String paramName = reqHeaderNames.nextElement();
+				if (StringUtils.isNotEmpty(paramName) && reqHeaderWhiteListeForModules.contains(paramName.toLowerCase()) )
+					executionContext.put(paramName, StringEscapeUtils.escapeHtml4(httpReq.getHeader(paramName)));
+					
+			}			
+		}
+		
+		//populate more IDP specific information to execution context
+		populateExecutionContext(executionContext, pendingReq, httpReq);
+				
+		//start process engine
+		startProcessEngine(pendingReq, executionContext);
+		
+	}
+
+	/**
+	 * 
+	 * 
+	 * @throws EAAFException
+	 */
+	abstract protected void populateExecutionContext(ExecutionContext executionContext, 
+			RequestImpl pendingReq, HttpServletRequest httpReq) throws EAAFException;
+	
+	/**
+	 * Starting a user consent evaluation
+	 * 
+	 * @param request
+	 * @param response
+	 * @param pendingReq
+	 * @throws ServletException
+	 * @throws IOException
+	 * @throws EAAFException
+	 */
+	private void sendSingleSignOnConsentsEvaluation(HttpServletRequest request,
+			HttpServletResponse response, RequestImpl pendingReq)
+			throws EAAFException { 
+			
+			log.debug("Starting SSO user-consents evaluation ...");
+		
+			//set authenticated flag to false, because user consents is required
+			pendingReq.setAuthenticated(false);
+			
+			//create execution context
+			ExecutionContext executionContext = new ExecutionContextImpl();
+			executionContext.put(ISSOManager.PROCESS_ENGINE_SSO_CONSENTS_EVALUATION, true);
+			
+			//start process engine
+			startProcessEngine(pendingReq, executionContext);
+		 
+	}
+	
+	
+	/**
+	 * Select a specific process and starting process engine
+	 * 
+	 * @param pendingReq
+	 * @param executionContext
+	 * @throws EAAFException
+	 */
+	private void startProcessEngine(RequestImpl pendingReq, ExecutionContext executionContext) throws EAAFException {
+		try {
+			//put pending-request ID on execurtionContext
+			executionContext.put(EAAFConstants.PROCESS_ENGINE_PENDINGREQUESTID, pendingReq.getPendingRequestId());			
+						
+			// create process instance
+			String processDefinitionId = ModuleRegistration.getInstance().selectProcess(executionContext);
+
+			if (processDefinitionId == null) {
+				log.warn("No suitable process found for PendingReqId " + pendingReq.getPendingRequestId() );
+				throw new EAAFException(
+						"process.02",
+						new Object[] {pendingReq.getPendingRequestId()}
+						,"No suitable process found for PendingReqId " + pendingReq.getPendingRequestId());
+				
+			}
+
+			String processInstanceId = processEngine.createProcessInstance(processDefinitionId, executionContext);
+
+			// keep process instance id in protocol pending-request
+			pendingReq.setProcessInstanceId(processInstanceId);
+
+			//store pending-request			
+			requestStoreage.storePendingRequest(pendingReq);
+									
+	    	// start process
+			processEngine.start(pendingReq);
+			
+		} catch (ProcessExecutionException e) {
+			Throwable cause = e.getCause();
+			if (cause != null && cause instanceof TaskExecutionException) {
+				Throwable taskCause = cause.getCause();
+				if (taskCause != null && taskCause instanceof EAAFException) {
+					EAAFException moaTaskCause = (EAAFException) taskCause;
+					log.warn(taskCause.getMessage(), taskCause);
+					throw moaTaskCause;
+				
+				}									
+			}
+			
+			throw new EAAFException(
+					"process.01", 
+					new Object[] { pendingReq.getProcessInstanceId(), pendingReq.getPendingRequestId() },
+					"Authentication process execution FAILED", 
+					e);
+		}
+		
+	}	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/RequestStorage.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/RequestStorage.java
new file mode 100644
index 00000000..7e0d4cc7
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/RequestStorage.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.auth;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IRequestStorage;
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessInstanceStoreDAO;
+import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException;
+import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
+import at.gv.egiz.eaaf.core.impl.utils.Random;
+import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils;
+
+@Service("RequestStorage")
+public class RequestStorage implements IRequestStorage{
+	private static final Logger log = LoggerFactory.getLogger(RequestStorage.class);
+	
+	@Autowired ITransactionStorage transactionStorage;
+	@Autowired ProcessInstanceStoreDAO processInstanceStore;
+	
+	@Override
+	public IRequest getPendingRequest(String pendingReqID) {
+		
+		try {
+			IRequest pendingRequest = transactionStorage.get(pendingReqID, IRequest.class);
+			if (pendingRequest == null) {
+				log.info("No PendingRequst found with pendingRequestID " + pendingReqID);			
+				return null;
+				
+			}
+					
+			//set transactionID and sessionID to Logger
+			TransactionIDUtils.setAllLoggingVariables(pendingRequest);
+						
+			return pendingRequest;
+		
+		} catch (EAAFException | NullPointerException e) {
+			log.info("No PendingRequst found with pendingRequestID " + pendingReqID);			
+			return null;
+			
+		}
+	}
+
+	@Override
+	public void storePendingRequest(IRequest pendingRequest) throws EAAFException {
+		try {			
+			if (pendingRequest instanceof IRequest) 
+				transactionStorage.put(((IRequest)pendingRequest).getPendingRequestId(), pendingRequest, -1);
+												
+			else
+				throw new EAAFException("PendigRequest is NOT of type 'IRequest'", null);
+				
+			
+		} catch (EAAFException e) {
+			log.warn("PendingRequest with ID=" + ((IRequest)pendingRequest).getPendingRequestId() +
+					" can not stored.", e);
+			throw new EAAFStorageException("PendingRequest with Id: " + ((IRequest)pendingRequest).getPendingRequestId()
+					+ " can not be stored", e);
+			
+		}
+		
+	}
+	
+	@Override
+	public void removePendingRequest(String requestID) {
+		
+		if (requestID != null) {
+			
+			//remove process-management execution instance
+			try {
+				IRequest pendingReq = getPendingRequest(requestID);
+						
+				if (pendingReq != null && 
+						pendingReq.getProcessInstanceId() != null)
+					processInstanceStore.remove(pendingReq.getProcessInstanceId());
+					
+			} catch (EAAFException e) {
+				log.warn("Removing process associated with pending-request:" + requestID + " FAILED.", e);
+				
+			}
+				
+			transactionStorage.remove(requestID);
+			
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.storage.IRequestStorage#changePendingRequestID(at.gv.egovernment.moa.id.moduls.IRequest)
+	 */
+	@Override
+	public String changePendingRequestID(IRequest pendingRequest) throws EAAFException {
+
+		if (pendingRequest instanceof RequestImpl) {
+			String newRequestID = Random.nextHexRandom32();
+			String oldRequestID = pendingRequest.getPendingRequestId();
+			
+			log.debug("Change pendingRequestID from " + pendingRequest.getPendingRequestId() 
+				+ " to " + newRequestID);
+			
+			((RequestImpl)pendingRequest).setPendingRequestId(newRequestID);			
+			transactionStorage.changeKey(oldRequestID, newRequestID, pendingRequest);
+			
+			//only delete oldRequestID, no change.			
+			
+			return newRequestID;
+						
+		} else {
+			log.error("PendingRequest object is not of type 'RequestImpl.class'");
+			throw new EAAFException("PendingRequest object is not of type 'RequestImpl.class'", null);
+		}
+		
+	}
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java
new file mode 100644
index 00000000..561f6f32
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java
@@ -0,0 +1,467 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.auth.builder;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.Base64Utils;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.data.PVPAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.idp.IAuthenticationDataBuilder;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IAuthProcessDataContainer;
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
+import at.gv.egiz.eaaf.core.exceptions.EAAFBuilderException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFParserException;
+import at.gv.egiz.eaaf.core.exceptions.XPathException;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.core.impl.idp.AuthenticationData;
+import at.gv.egiz.eaaf.core.impl.idp.auth.data.SimpleIdentityLinkAssertionParser;
+import at.gv.egiz.eaaf.core.impl.utils.XPathUtils;
+ 
+
+public abstract class AbstractAuthenticationDataBuilder implements IAuthenticationDataBuilder {
+	private static final Logger log = LoggerFactory.getLogger(AbstractAuthenticationDataBuilder.class);		
+	protected Collection<String> includedToGenericAuthData = null;	
+	@Autowired protected IConfiguration basicConfig;
+	
+	protected void generateBasicAuthData(AuthenticationData authData, IRequest pendingReq, 
+			IAuthProcessDataContainer authProcessData) throws EAAFBuilderException, EAAFConfigurationException, XPathException, DOMException, EAAFParserException {
+		
+		if (authProcessData.getGenericSessionDataStorage() != null &&  
+				!authProcessData.getGenericSessionDataStorage().isEmpty())
+			includedToGenericAuthData = authProcessData.getGenericSessionDataStorage().keySet();
+		else
+			includedToGenericAuthData = new ArrayList<String>();
+			
+		//####################################################
+		//set general authData info's
+		authData.setAuthenticationIssuer(pendingReq.getAuthURL());
+		authData.setSsoSession(pendingReq.needSingleSignOnFunctionality());			
+		authData.setBaseIDTransferRestrication(pendingReq.getServiceProviderConfiguration().hasBaseIdTransferRestriction());
+		
+	
+		//####################################################
+		//parse user info's from identityLink
+		IIdentityLink idlFromPVPAttr = null;
+		IIdentityLink identityLink = authProcessData.getIdentityLink();		
+		if (identityLink != null) {
+			parseBasicUserInfosFromIDL(authData, identityLink, includedToGenericAuthData);
+		
+		} else {
+			// identityLink is not direct in MOASession
+			String pvpAttrIDL = authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.EID_IDENTITY_LINK_NAME, String.class);
+				//find PVP-Attr. which contains the IdentityLink
+			if (StringUtils.isNotEmpty(pvpAttrIDL)) {
+				log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.EID_IDENTITY_LINK_FRIENDLY_NAME
+						+ " --> Parse basic user info's from that attribute.");
+				InputStream idlStream = null;
+				try {
+					idlStream = new ByteArrayInputStream(Base64Utils.decodeFromString(pvpAttrIDL));				
+					idlFromPVPAttr = new SimpleIdentityLinkAssertionParser(idlStream).parseIdentityLink();
+					parseBasicUserInfosFromIDL(authData, idlFromPVPAttr, includedToGenericAuthData);
+					
+					//set identitylink into AuthProcessData
+					authProcessData.setIdentityLink(idlFromPVPAttr);;	
+					
+				} catch (EAAFParserException e) {
+					log.warn("Received IdentityLink is not valid", e);
+					
+				} catch (Exception e) {
+					log.warn("Received IdentityLink is not valid", e);
+					
+				} finally {
+					try {
+						includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_IDENTITY_LINK_NAME);
+						if (idlStream != null)						
+							idlStream.close();
+						
+					} catch (IOException e) {
+						log.warn("Close InputStream FAILED.", e);
+						
+					}						
+				}					
+			}
+			
+			//if no basic user info's are set yet, parse info's single PVP-Attributes
+			if (StringUtils.isEmpty(authData.getFamilyName())) {
+				log.debug("No IdentityLink found or not parseable --> Parse basic user info's from single PVP-Attributes.");
+				authData.setFamilyName(authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.PRINCIPAL_NAME_NAME, String.class));		
+				authData.setGivenName(authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.GIVEN_NAME_NAME, String.class));		
+				authData.setDateOfBirth(authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.BIRTHDATE_NAME, String.class));
+				authData.setIdentificationValue(authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.EID_SOURCE_PIN_NAME, String.class));		
+				authData.setIdentificationType(authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.EID_SOURCE_PIN_TYPE_NAME, String.class));
+				
+				//remove corresponding keys from genericSessionData if exists
+				includedToGenericAuthData.remove(PVPAttributeDefinitions.PRINCIPAL_NAME_NAME);
+				includedToGenericAuthData.remove(PVPAttributeDefinitions.GIVEN_NAME_NAME);
+				includedToGenericAuthData.remove(PVPAttributeDefinitions.BIRTHDATE_NAME);
+				includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_SOURCE_PIN_NAME);
+				includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_SOURCE_PIN_TYPE_NAME);
+			}
+							
+		}
+		
+		if (authData.getIdentificationType() != null && 
+				!authData.getIdentificationType().equals(EAAFConstants.URN_PREFIX_BASEID)) {
+			log.trace("IdentificationType is not a baseID --> clear it. ");
+			authData.setBPK(authData.getIdentificationValue());
+			authData.setBPKType(authData.getIdentificationType());
+			
+			authData.setIdentificationValue(null);
+			authData.setIdentificationType(null);								
+		}
+		
+		//####################################################
+		//set QAA level
+		includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME);
+		String currentLoA = null;
+		if (StringUtils.isNotEmpty(authProcessData.getQAALevel()))
+			currentLoA = authProcessData.getQAALevel();			
+		else {
+			currentLoA = authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, String.class);
+			if (StringUtils.isNotEmpty(currentLoA)) {
+				log.debug("Find PVP-Attr '" + PVPAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_FRIENDLY_NAME + "':" + currentLoA
+						+ " --> Parse QAA-Level from that attribute.");
+				
+			}
+		}
+		if (StringUtils.isNotEmpty(currentLoA)) {					
+			 if (currentLoA.startsWith(EAAFConstants.EIDAS_QAA_PREFIX)) {
+				authData.seteIDASLoA(currentLoA);
+					
+			 } else
+				 log.info("Only eIDAS LoAs are supported by this implementation");
+				 
+		} else {
+			log.info("No QAA level found. Set to default level " + EAAFConstants.EIDAS_QAA_LOW);
+			authData.seteIDASLoA(EAAFConstants.EIDAS_QAA_LOW); 		
+		
+		}
+
+		//####################################################
+		//set isForeigner flag
+		//TODO: change to new eIDAS-token attribute identifier
+		if (authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.EID_STORK_TOKEN_NAME) != null) {
+			log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.EID_STORK_TOKEN_FRIENDLY_NAME
+					+ " --> Set 'isForeigner' flag to TRUE");
+			authData.setForeigner(true);
+			
+		} else {		
+			authData.setForeigner(authProcessData.isForeigner());
+			
+		}
+		
+		//####################################################
+		//set citizen country-code
+		includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_ISSUING_NATION_NAME);
+		String pvpCCCAttr = authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.EID_ISSUING_NATION_NAME, String.class);
+		if (StringUtils.isNotEmpty(pvpCCCAttr)) {
+			authData.setCiticenCountryCode(pvpCCCAttr);
+			log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.EID_ISSUING_NATION_FRIENDLY_NAME);
+			
+		} else {
+			if (authData.isForeigner()) {
+				//TODO!!!!
+								
+			} else {
+				authData.setCiticenCountryCode(basicConfig.getBasicConfiguration(
+						IConfiguration.CONFIG_PROPS_AUTH_DEFAULT_COUNTRYCODE, 
+						EAAFConstants.COUNTRYCODE_AUSTRIA));
+				
+			}			
+		}
+		
+		
+		//####################################################
+		// set bPK and IdentityLink  
+		String pvpbPKValue = getbPKValueFromPVPAttribute(authProcessData);
+		String pvpbPKTypeAttr = getbPKTypeFromPVPAttribute(authProcessData);				
+		Pair<String, String> pvpEncbPKAttr = getEncryptedbPKFromPVPAttribute(authProcessData, authData, pendingReq.getServiceProviderConfiguration());
+
+		//check if a unique ID for this citizen exists
+		if (StringUtils.isEmpty(authData.getIdentificationValue()) && 
+				StringUtils.isEmpty(pvpbPKValue) && StringUtils.isEmpty(authData.getBPK()) &&
+				pvpEncbPKAttr == null) {
+			log.info("Can not build authData, because moaSession include no bPK, encrypted bPK or baseID");
+			throw new EAAFBuilderException("builder.08", new Object[]{"No " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME
+					+ " or " + PVPAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME 
+					+ " or " + PVPAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME},
+					"No " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME
+					+ " or " + PVPAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME 
+					+ " or " + PVPAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME);
+			
+		}
+							
+		// baseID is in MOASesson --> calculate bPK directly
+		if (StringUtils.isNotEmpty(authData.getIdentificationValue())) {
+			log.debug("Citizen baseID is in MOASession --> calculate bPK from this.");
+			Pair<String, String> result = buildOAspecificbPK(pendingReq, authData);
+			authData.setBPK(result.getFirst());
+			authData.setBPKType(result.getSecond());
+			
+			//check if bPK already added to AuthData matches OA					
+		} else if (StringUtils.isNotEmpty(authData.getBPK()) 
+				&& matchsReceivedbPKToOnlineApplication(pendingReq.getServiceProviderConfiguration(), authData.getBPKType()) ) { 
+			log.debug("Correct bPK is already included in AuthData.");
+
+			//check if bPK received by PVP-Attribute matches OA
+		} else if (StringUtils.isNotEmpty(pvpbPKValue) && 
+				matchsReceivedbPKToOnlineApplication(pendingReq.getServiceProviderConfiguration(), pvpbPKTypeAttr)) {
+			log.debug("Receive correct bPK from PVP-Attribute");
+			authData.setBPK(pvpbPKValue);
+			authData.setBPKType(pvpbPKTypeAttr);
+			
+			//check if decrypted bPK exists
+		} else if (pvpEncbPKAttr != null) {
+			log.debug("Receive bPK as encrypted bPK and decryption was possible.");
+			authData.setBPK(pvpEncbPKAttr.getFirst());
+			authData.setBPKType(pvpEncbPKAttr.getSecond());
+		
+			//ask SZR to get bPK
+		} else {
+			String notValidbPK = authData.getBPK();  
+			String notValidbPKType = authData.getBPKType();					
+			if (StringUtils.isEmpty(notValidbPK) && 
+					StringUtils.isEmpty(notValidbPKType)) {
+				notValidbPK = pvpbPKValue;
+				notValidbPKType = pvpbPKTypeAttr;
+				
+				if (StringUtils.isEmpty(notValidbPK) && 
+						StringUtils.isEmpty(notValidbPKType)) {
+					log.error("No bPK in MOASession. THIS error should not occur any more.");
+					throw new NullPointerException("No bPK in MOASession. THIS error should not occur any more.");							
+				}						
+			}	
+								
+			Pair<String, String> baseIDFromSZR = getbaseIDFromSZR(authData, notValidbPK, notValidbPKType);
+			if (baseIDFromSZR != null) {
+				log.info("Receive citizen baseID from SRZ. Authentication can be completed");
+				authData.setIdentificationValue(baseIDFromSZR.getFirst());
+				authData.setIdentificationType(baseIDFromSZR.getSecond());
+				Pair<String, String> result = buildOAspecificbPK(pendingReq, authData);
+				authData.setBPK(result.getFirst());
+				authData.setBPKType(result.getSecond());
+				
+			} else {
+				log.warn("Can not build authData, because moaSession include no valid bPK, encrypted bPK or baseID");
+				throw new EAAFBuilderException("builder.08", new Object[]{"No valid " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME
+						+ " or " + PVPAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME 
+						+ " or " + PVPAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME},
+						"No valid " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME
+						+ " or " + PVPAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME 
+						+ " or " + PVPAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME);
+				
+			}					
+		}
+		
+		//build IdentityLink
+		if (authProcessData.getIdentityLink() != null)
+			authData.setIdentityLink(buildOAspecificIdentityLink(
+					pendingReq.getServiceProviderConfiguration(), 
+					authProcessData.getIdentityLink(), 
+					authData.getBPK(), 
+					authData.getBPKType()));
+		 else 
+			log.info("Can NOT set IdentityLink. Msg: No IdentityLink found");
+			            	                        		
+	}
+	
+	//extract a encrypted bPK from PVP attrobute
+	protected abstract Pair<String, String> getEncryptedbPKFromPVPAttribute(IAuthProcessDataContainer authProcessDataContainer,
+			AuthenticationData authData, ISPConfiguration spConfig) throws EAAFBuilderException;
+	
+	//request baseId from SRZ
+	protected abstract Pair<String, String> getbaseIDFromSZR(AuthenticationData authData, String notValidbPK,
+			String notValidbPKType);
+	
+	
+	protected Pair<String, String> buildOAspecificbPK(IRequest pendingReq, AuthenticationData authData) throws EAAFBuilderException {
+		ISPConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
+		
+		String baseID = authData.getIdentificationValue();
+		String baseIDType = authData.getIdentificationType();		
+		Pair<String, String> sectorSpecId = null;
+		
+		if (EAAFConstants.URN_PREFIX_BASEID.equals(baseIDType)) {			
+			//SAML1 legacy target parameter work-around
+			String spTargetId = oaParam.getAreaSpecificTargetIdentifier();
+        	log.debug("Use OA target identifier '" + spTargetId + "' from configuration");
+	        	
+	        //calculate sector specific unique identifier
+	        sectorSpecId = new BPKBuilder().generateAreaSpecificPersonIdentifier(baseID, spTargetId);
+	        				 			 			 
+		 } else {
+			 log.error("!!!baseID-element does not include a baseID. This should not be happen any more!!!");                           	
+     		 sectorSpecId = Pair.newInstance(baseID, baseIDType);
+     		 
+		 }
+		
+		log.trace("Authenticate user with bPK:" + sectorSpecId.getFirst() + " Type:" + sectorSpecId.getSecond());
+		return sectorSpecId;
+        
+	}
+	
+	protected IIdentityLink buildOAspecificIdentityLink(ISPConfiguration spConfig, IIdentityLink idl, String bPK, String bPKType) throws EAAFConfigurationException, XPathException, DOMException, EAAFParserException {
+		if (spConfig.hasBaseIdTransferRestriction()) {
+			log.debug("SP: " + spConfig.getUniqueIdentifier() + " has baseId transfer restriction. Remove baseId from IDL ...");
+            Element idlassertion = idl.getSamlAssertion();
+            //set bpk/wpbk; 
+	        Node prIdentification = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH);
+	        prIdentification.getFirstChild().setNodeValue(bPK);
+            //set bkp/wpbk type
+            Node prIdentificationType = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_IDENT_TYPE_XPATH);
+            prIdentificationType.getFirstChild().setNodeValue(bPKType);
+
+            SimpleIdentityLinkAssertionParser idlparser = new SimpleIdentityLinkAssertionParser(idlassertion);
+            return idlparser.parseIdentityLink();
+                                			
+        } else
+        	return idl;
+        			
+	}
+	
+	/**
+	 * Check a bPK-Type against a Service-Provider configuration <br>
+	 * If bPK-Type is <code>null</code> the result is <code>false</code>.
+	 * 
+	 * @param oaParam Service-Provider configuration, never null
+	 * @param bPKType bPK-Type to check
+	 * @return true, if bPK-Type matchs to Service-Provider configuration, otherwise false 
+	 */
+	private boolean matchsReceivedbPKToOnlineApplication(ISPConfiguration oaParam, String bPKType) {						
+		return oaParam.getAreaSpecificTargetIdentifier().equals(bPKType);
+
+	}
+
+	/**
+	 * Parse information from an IdentityLink into AuthData object
+	 * 
+	 * @param authData
+	 * @param identityLink
+	 * @param includedGenericSessionData
+	 */
+	private void parseBasicUserInfosFromIDL(AuthenticationData authData, IIdentityLink identityLink, Collection<String> includedGenericSessionData) {
+		authData.setIdentificationValue(identityLink.getIdentificationValue());
+		authData.setIdentificationType(identityLink.getIdentificationType());
+
+		authData.setGivenName(identityLink.getGivenName());
+		authData.setFamilyName(identityLink.getFamilyName());
+		authData.setDateOfBirth(identityLink.getDateOfBirth());
+		
+		//remove corresponding keys from genericSessionData if exists
+		includedGenericSessionData.remove(PVPAttributeDefinitions.PRINCIPAL_NAME_NAME);
+		includedGenericSessionData.remove(PVPAttributeDefinitions.GIVEN_NAME_NAME);
+		includedGenericSessionData.remove(PVPAttributeDefinitions.BIRTHDATE_NAME);
+		includedGenericSessionData.remove(PVPAttributeDefinitions.EID_SOURCE_PIN_NAME);
+		includedGenericSessionData.remove(PVPAttributeDefinitions.EID_SOURCE_PIN_TYPE_NAME);
+		
+	}
+	
+	/**
+	 * Get bPK from PVP Attribute 'BPK_NAME', which could be exist in
+	 * MOASession as 'GenericData' <br> <pre><code>session.getGenericDataFromSession(PVPConstants.BPK_NAME, String.class)</code></pre>
+	 * 
+	 * @param session MOASession, but never null
+	 * @return bPK, which was received by PVP-Attribute, or <code>null</code> if no attribute exists
+	 */
+	private String getbPKValueFromPVPAttribute(IAuthProcessDataContainer session) {
+		String pvpbPKValueAttr = session.getGenericDataFromSession(PVPAttributeDefinitions.BPK_NAME, String.class);
+		if (StringUtils.isNotEmpty(pvpbPKValueAttr)) {
+			
+			//fix a wrong bPK-value prefix, which was used in some PVP Standardportal implementations
+			if (pvpbPKValueAttr.startsWith("bPK:")) {
+				log.warn("Attribute " + PVPAttributeDefinitions.BPK_NAME 
+					+ " contains a not standardize prefix! Staring attribute value correction process ...");
+				pvpbPKValueAttr = pvpbPKValueAttr.substring("bPK:".length());
+				
+			}
+			
+			String[] spitted = pvpbPKValueAttr.split(":");
+			if (spitted.length != 2) {
+				log.warn("Attribute " + PVPAttributeDefinitions.BPK_NAME + " has a wrong encoding and can NOT be USED!"
+						+ " Value:" + pvpbPKValueAttr);
+				return null;
+				
+			}
+			log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME);
+			return spitted[1];
+			
+		}
+		
+		return null;
+	}
+
+	/**
+	 * Get bPK-Type from PVP Attribute 'EID_SECTOR_FOR_IDENTIFIER_NAME', which could be exist in
+	 * MOASession as 'GenericData' <br> <pre><code>session.getGenericDataFromSession(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME, String.class)</code></pre>
+	 * 
+	 * @param session MOASession, but never null
+	 * @return bPKType, which was received by PVP-Attribute, or <code>null</code> if no attribute exists
+	 */
+	private String getbPKTypeFromPVPAttribute(IAuthProcessDataContainer session) {
+		String pvpbPKTypeAttr = session.getGenericDataFromSession(PVPAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME, String.class); 
+		if (StringUtils.isNotEmpty(pvpbPKTypeAttr)) {
+			
+			//fix a wrong bPK-Type encoding, which was used in some PVP Standardportal implementations
+			if (pvpbPKTypeAttr.startsWith(EAAFConstants.URN_PREFIX_CDID) && 
+					!pvpbPKTypeAttr.substring(EAAFConstants.URN_PREFIX_CDID.length(), 
+							EAAFConstants.URN_PREFIX_CDID.length() + 1).equals("+")) {				
+				log.warn("Receive uncorrect encoded bBKType attribute " + pvpbPKTypeAttr + " Starting attribute value correction ... ");
+				pvpbPKTypeAttr = EAAFConstants.URN_PREFIX_CDID + "+" + pvpbPKTypeAttr.substring(EAAFConstants.URN_PREFIX_CDID.length() + 1); 
+				
+			}
+			log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME);
+			return pvpbPKTypeAttr;
+		}
+		
+		return null;
+
+
+		/*
+		 * INFO: This code could be used to extract the bPKType from 'PVPConstants.BPK_NAME',
+		 *       because the prefix of BPK_NAME attribute contains the postfix of the bPKType
+		 *       
+		 *       Now, all PVP Standardportals should be able to send 'EID_SECTOR_FOR_IDENTIFIER'
+		 *       PVP attributes  
+		 */
+//		String pvpbPKValueAttr = session.getGenericDataFromSession(PVPConstants.BPK_NAME, String.class);
+//		String[] spitted = pvpbPKValueAttr.split(":");
+//		if (MiscUtil.isEmpty(authData.getBPKType())) {
+//			Logger.debug("PVP assertion contains NO bPK/wbPK target attribute. " +
+//					"Starting target extraction from bPK/wbPK prefix ...");
+//			//exract bPK/wbPK type from bpk attribute value prefix if type is 
+//			//not transmitted as single attribute
+//		    Pattern pattern = Pattern.compile("[a-zA-Z]{2}(-[a-zA-Z]+)?");
+//		    Matcher matcher = pattern.matcher(spitted[0]);
+//		    if (matcher.matches()) {
+//		    	//find public service bPK
+//		    	authData.setBPKType(Constants.URN_PREFIX_CDID + "+" + spitted[0]);
+//		    	Logger.debug("Found bPK prefix. Set target to " + authData.getBPKType());
+//		    	   
+//		    } else {
+//		    	//find business service wbPK
+//		    	authData.setBPKType(Constants.URN_PREFIX_WBPK+ "+" + spitted[0]);
+//		    	Logger.debug("Found wbPK prefix. Set target to " + authData.getBPKType());
+//		    	   
+//		    }			    	  				
+//		}
+		
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BPKBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BPKBuilder.java
new file mode 100644
index 00000000..62a57dd1
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BPKBuilder.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egiz.eaaf.core.impl.idp.auth.builder;
+
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.Base64Utils;
+
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.exceptions.EAAFBuilderException;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+
+/**
+ * Builder for the bPK, as defined in
+ * <code>&quot;Ableitung f&uml;r die bereichsspezifische Personenkennzeichnung&quot;</code>
+ * version <code>1.0.1</code> from <code>&quot;reference.e-government.gv.at&quot;</code>.
+ *
+ */
+public class BPKBuilder {
+	private static final Logger log = LoggerFactory.getLogger(BPKBuilder.class);
+	
+	/**
+	 * Calculates an area specific unique person-identifier from a baseID
+	 * 
+	 * @param baseID baseId from user but never null
+	 * @param targetIdentifier target identifier for area specific identifier calculation but never null
+	 * @return Pair<unique person identifier for this target, targetArea> but never null
+	 * @throws EAAFBuilderException if some input data are not valid 
+	 */
+	public Pair<String, String> generateAreaSpecificPersonIdentifier(String baseID, String targetIdentifier) throws EAAFBuilderException {
+		return generateAreaSpecificPersonIdentifier(baseID, EAAFConstants.URN_PREFIX_BASEID, targetIdentifier);
+		
+	}
+	
+	/**
+	 * Calculates an area specific unique person-identifier from an unique identifier with a specific type
+	 * 
+	 * @param baseID baseId from user but never null
+	 * @param baseIdType Type of the baseID but never null
+	 * @param targetIdentifier target identifier for area specific identifier calculation but never null
+	 * @return Pair<unique person identifier for this target, targetArea> but never null
+	 * @throws EAAFBuilderException if some input data are not valid 
+	 */
+	public Pair<String, String> generateAreaSpecificPersonIdentifier(String baseID, String baseIdType, String targetIdentifier) throws EAAFBuilderException{
+		if (StringUtils.isEmpty(baseID))
+			throw new EAAFBuilderException("builder.00", new Object[]{"baseID is empty or null"},
+					"BaseId is empty or null");
+
+		if (StringUtils.isEmpty(baseIdType))
+			throw new EAAFBuilderException("builder.00", new Object[]{"the type of baseID is empty or null"},
+					"Type of baseId is empty or null");
+		
+		if (StringUtils.isEmpty(targetIdentifier)) 
+			throw new EAAFBuilderException("builder.00", new Object[]{"SP specific target identifier is empty or null"},
+					"SP specific target identifier is empty or null");
+
+		if (baseIdType.equals(EAAFConstants.URN_PREFIX_BASEID)) {
+			log.trace("Find baseID. Starting unique identifier caluclation for this target");
+			
+			if (targetIdentifier.startsWith(EAAFConstants.URN_PREFIX_CDID) || 
+					targetIdentifier.startsWith(EAAFConstants.URN_PREFIX_WBPK)) {
+				log.trace("Calculate bPK, wbPK, or STORK identifier for target: " + targetIdentifier);
+				return Pair.newInstance(calculatebPKwbPK(baseID + "+" + targetIdentifier), targetIdentifier);
+													
+			} else if (targetIdentifier.startsWith(EAAFConstants.URN_PREFIX_EIDAS)) {
+				log.trace("Calculate eIDAS identifier for target: " + targetIdentifier);
+				String[] splittedTarget = targetIdentifier.split("\\+");
+				String cititzenCountryCode = splittedTarget[1];
+				String eIDASOutboundCountry = splittedTarget[2];				 
+				 
+				if (cititzenCountryCode.equalsIgnoreCase(eIDASOutboundCountry)) {
+					log.warn("Suspect configuration FOUND!!! CitizenCountry equals DestinationCountry");
+					 
+				}
+				return buildeIDASIdentifer(baseID, baseIdType, cititzenCountryCode, eIDASOutboundCountry);
+				
+				
+			} else
+				throw new EAAFBuilderException("builder.00", 
+						new Object[]{"Target identifier: " + targetIdentifier + " is NOT allowed or unknown"},
+						"Target identifier: " + targetIdentifier + " is NOT allowed or unknown");
+		
+		} else {
+			log.trace("BaseID is not of type " + EAAFConstants.URN_PREFIX_BASEID + ". Check type against requested target ...");
+			if (baseIdType.equals(targetIdentifier)) {
+				log.debug("Unique identifier is already area specific. Is nothing todo");
+				return Pair.newInstance(baseID, targetIdentifier);
+				
+			} else {
+				log.warn("Get unique identifier for target: " + baseIdType + " but target: " + targetIdentifier + " is required!");
+				throw new EAAFBuilderException("builder.00", 
+						new Object[]{"Get unique identifier for target: " + baseIdType + " but target: " + targetIdentifier + " is required"},
+						"Get unique identifier for target: " + baseIdType + " but target: " + targetIdentifier + " is required");
+				
+			}			
+		}						
+	}
+	
+	
+    /**
+     * Builds the eIDAS from the given parameters.
+     *
+     * @param baseID baseID of the citizen
+     * @param baseIDType Type of the baseID
+     * @param sourceCountry CountryCode of that country, which build the eIDAs ID
+     * @param destinationCountry CountryCode of that country, which receives the eIDAs ID
+     * 
+     * @return Pair<eIDAs, bPKType> in a BASE64 encoding
+     * @throws EAAFBuilderException if some input data are not valid 
+     */
+    private Pair<String, String> buildeIDASIdentifer(String baseID, String baseIDType, String sourceCountry, String destinationCountry)
+            throws EAAFBuilderException {        
+        String bPK = null;
+        String bPKType = null;
+        
+        // check if we have been called by public sector application
+        if (baseIDType.startsWith(EAAFConstants.URN_PREFIX_BASEID)) {
+        	bPKType = EAAFConstants.URN_PREFIX_EIDAS + "+" + sourceCountry + "+" + destinationCountry;
+            log.debug("Building eIDAS identification from: [identValue]+" + bPKType);         
+            bPK = calculatebPKwbPK(baseID + "+"  + bPKType);
+            
+        } else { // if not, sector identification value is already calculated by BKU
+            log.debug("eIDAS eIdentifier already provided by BKU");
+            bPK = baseID;
+        }
+
+        if ((StringUtils.isEmpty(bPK) ||
+                StringUtils.isEmpty(sourceCountry) ||
+                	StringUtils.isEmpty(destinationCountry))) {
+            throw new EAAFBuilderException("builder.00",
+                    new Object[]{"eIDAS-ID", "Unvollständige Parameterangaben: identificationValue=" +
+                            bPK + ", Zielland=" + destinationCountry + ", Ursprungsland=" + sourceCountry}
+                    ,"eIDAS-ID: Unvollständige Parameterangaben: identificationValue=" +
+                            bPK + ", Zielland=" + destinationCountry + ", Ursprungsland=" + sourceCountry);
+        }
+        
+        log.debug("Building eIDAS identification from: " + sourceCountry+"/"+destinationCountry+"/" + "[identValue]");
+        String eIdentifier = sourceCountry + "/" + destinationCountry + "/" + bPK;
+        
+        return Pair.newInstance(eIdentifier, bPKType);
+    }
+	    
+	public static String encryptBPK(String bpk, String target, PublicKey publicKey) throws EAAFBuilderException {		
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+		if (target.startsWith(EAAFConstants.URN_PREFIX_CDID + "+"))
+			target = target.substring((EAAFConstants.URN_PREFIX_CDID + "+").length());
+		
+		String input = "V1::urn:publicid:gv.at:cdid+" + target + "::"
+		    + bpk + "::"
+		    + sdf.format(new Date());
+		System.out.println(input);
+		byte[] result;
+		try {
+			byte[] inputBytes = input.getBytes("ISO-8859-1");
+			result = encrypt(inputBytes, publicKey);
+			return new String(Base64Utils.encode(result), "ISO-8859-1").replaceAll("\r\n", "");
+			//return new String(Base64Utils.encode(result, "ISO-8859-1")).replaceAll("\r\n", "");
+			
+			
+		} catch (Exception e) {
+			throw new EAAFBuilderException("bPK encryption FAILED", null,
+					e.getMessage(), e);
+			
+		}		
+	}
+
+	public static String decryptBPK(String encryptedBpk, String target, PrivateKey privateKey) throws EAAFBuilderException {
+		String decryptedString;
+		try {
+			//byte[] encryptedBytes = Base64Utils.decode(encryptedBpk, false, "ISO-8859-1");
+			byte[] encryptedBytes = Base64Utils.decode(encryptedBpk.getBytes("ISO-8859-1")); 
+			byte[] decryptedBytes = decrypt(encryptedBytes, privateKey);
+			decryptedString = new String(decryptedBytes, "ISO-8859-1");
+			
+		} catch (Exception e) {
+			throw new EAAFBuilderException("bPK decryption FAILED", null, 
+					e.getMessage(), e);
+			
+		}
+		
+		String tmp = decryptedString.substring(decryptedString.indexOf('+') + 1);
+		String sector = tmp.substring(0, tmp.indexOf("::"));
+		tmp = tmp.substring(tmp.indexOf("::") + 2);
+		String bPK = tmp.substring(0, tmp.indexOf("::"));
+
+		if (target.startsWith(EAAFConstants.URN_PREFIX_CDID + "+"))
+			target = target.substring((EAAFConstants.URN_PREFIX_CDID + "+").length());
+		
+		if (target.equals(sector))
+			return bPK;
+		
+		else {
+			log.error("Decrypted bPK does not match to request bPK target.");
+			return null;
+		}		
+	}
+        
+    private String calculatebPKwbPK(String basisbegriff) throws EAAFBuilderException {
+    	try {
+            MessageDigest md = MessageDigest.getInstance("SHA-1");
+            byte[] hash = md.digest(basisbegriff.getBytes("ISO-8859-1"));
+            String hashBase64 = new String(Base64Utils.encode(hash), "ISO-8859-1").replaceAll("\r\n", ""); //Base64Utils.encode(hash);
+            return hashBase64;
+            
+        } catch (Exception ex) {
+            throw new EAAFBuilderException("builder.00", new Object[]{"bPK/wbPK", ex.toString()}, 
+            		ex.getMessage(), ex);
+            
+        }
+    	
+    }
+    
+	private static byte[] encrypt(byte[] inputBytes, PublicKey publicKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
+		byte[] result;
+		Cipher cipher = null;
+		try {
+			cipher = Cipher.getInstance("RSA/ECB/OAEPPadding"); // try with bouncycastle
+			
+		} catch(NoSuchAlgorithmException e) {
+			cipher = Cipher.getInstance("RSA/ECB/OAEP"); // try with iaik provider
+		}
+		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+		result = cipher.doFinal(inputBytes);
+		
+		return result;
+	}
+
+	private static byte[] decrypt(byte[] encryptedBytes, PrivateKey privateKey) 
+			throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
+		byte[] result;
+		Cipher cipher = null;
+		try {
+			cipher = Cipher.getInstance("RSA/ECB/OAEPPadding"); // try with bouncycastle
+			
+		} catch(NoSuchAlgorithmException e) {
+			cipher = Cipher.getInstance("RSA/ECB/OAEP"); // try with iaik provider
+			
+		}
+		cipher.init(Cipher.DECRYPT_MODE, privateKey);
+		result = cipher.doFinal(encryptedBytes);
+		return result;
+		
+	}
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java
new file mode 100644
index 00000000..3fca5300
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.auth.data;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.idp.EAAFAuthProcessDataConstants;
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IAuthProcessDataContainer;
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
+import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException;
+
+public class AuthProcessDataWrapper implements IAuthProcessDataContainer, EAAFAuthProcessDataConstants {
+	private static final Logger log = LoggerFactory.getLogger(AuthProcessDataWrapper.class);
+	
+	protected Map<String, Object> authProcessData;
+	
+	public AuthProcessDataWrapper(Map<String, Object> authProcessData) {
+		this.authProcessData = authProcessData;
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getIssueInstant()
+	 */
+	@Override
+	public String getIssueInstant() {
+		return wrapStringObject(VALUE_ISSUEINSTANT, null, String.class);
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setIssueInstant(java.lang.String)
+	 */
+	@Override
+	public void setIssueInstant(String issueInstant) {
+		authProcessData.put(VALUE_ISSUEINSTANT, issueInstant);
+
+	}
+	
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#isAuthenticated()
+	 */
+	@Override
+	public boolean isAuthenticated() {
+		return wrapStringObject(FLAG_IS_AUTHENTICATED, false, Boolean.class);
+
+	}
+	
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setAuthenticated(boolean)
+	 */
+	@Override
+	public void setAuthenticated(boolean authenticated) {
+		authProcessData.put(FLAG_IS_AUTHENTICATED, authenticated);
+
+	}
+	
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getIdentityLink()
+	 */
+	@Override
+	public IIdentityLink getIdentityLink() {
+		return wrapStringObject(VALUE_IDENTITYLINK, null, IIdentityLink.class);
+		
+	}
+
+	
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setIdentityLink(at.gv.egovernment.moa.id.auth.data.IdentityLink)
+	 */
+	@Override
+	public void setIdentityLink(IIdentityLink identityLink) {
+		authProcessData.put(VALUE_IDENTITYLINK, identityLink);
+
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#isMandateUsed()
+	 */
+	@Override
+	public boolean isMandateUsed() {
+		return wrapStringObject(FLAG_USE_MANDATE, false, Boolean.class);
+	}
+	
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setUseMandates(boolean)
+	 */
+	@Override
+	public void setUseMandates(boolean useMandates) {
+		authProcessData.put(FLAG_USE_MANDATE, useMandates);
+
+	}
+	
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getQAALevel()
+	 */
+	@Override
+	public String getQAALevel() {
+		return wrapStringObject(VALUE_QAALEVEL, null, String.class);
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setQAALevel(java.lang.String)
+	 */
+	@Override
+	public void setQAALevel(String qAALevel) {
+		authProcessData.put(VALUE_QAALEVEL, qAALevel);
+
+	}
+	
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#isForeigner()
+	 */
+	@Override
+	public boolean isForeigner() {
+		return wrapStringObject(FLAG_IS_FOREIGNER, false, Boolean.class);
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setForeigner(boolean)
+	 */
+	@Override
+	public void setForeigner(boolean isForeigner) {
+		authProcessData.put(FLAG_IS_FOREIGNER, isForeigner);
+
+	}
+	
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#isOW()
+	 */
+	@Override
+	public boolean isOW() {
+		return wrapStringObject(FLAG_IS_ORGANWALTER, false, Boolean.class);
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setOW(boolean)
+	 */
+	@Override
+	public void setOW(boolean isOW) {
+		authProcessData.put(FLAG_IS_ORGANWALTER, isOW);
+
+	}
+	
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getSessionCreated()
+	 */
+	@Override
+	public Date getSessionCreated() {
+		return wrapStringObject(EAAFConstants.AUTH_DATA_CREATED, null, Date.class);
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getGenericSessionDataStorage()
+	 */
+	@Override
+	public Map<String, Object> getGenericSessionDataStorage() {
+		Map<String, Object> result = new HashMap<String, Object>();		
+		for (String el : authProcessData.keySet()) {
+			if (el.startsWith(GENERIC_PREFIX))
+				result.put(el.substring(GENERIC_PREFIX.length()), authProcessData.get(el));
+			
+		}
+		
+		return result;
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getGenericDataFromSession(java.lang.String)
+	 */
+	@Override
+	public Object getGenericDataFromSession(String key) {
+		return authProcessData.get(GENERIC_PREFIX + key); 
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getGenericDataFromSession(java.lang.String, java.lang.Class)
+	 */
+	@Override
+	public <T> T getGenericDataFromSession(String key, Class<T> clazz) {
+		return wrapStringObject(GENERIC_PREFIX + key, null, clazz);
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setGenericDataToSession(java.lang.String, java.lang.Object)
+	 */
+	@Override
+	public void setGenericDataToSession(String key, Object object) throws EAAFStorageException {
+		authProcessData.put(GENERIC_PREFIX + key, object);
+
+	}
+	
+	protected <T> T wrapStringObject(String key, Object defaultValue, Class<T> clazz) {		
+		if (StringUtils.isNotEmpty(key)) {
+			Object obj = authProcessData.get(key);
+			if (obj != null && clazz.isInstance(obj))
+				return (T) obj;
+		}
+		
+		if (defaultValue == null)
+			return null;
+		
+		else if (clazz.isInstance(defaultValue))
+			return (T)defaultValue;
+			
+		else {
+			log.error("DefaultValue: " + defaultValue.getClass().getName() + " is not of Type:" + clazz.getName());
+			throw new IllegalStateException("DefaultValue: " + defaultValue.getClass().getName() + " is not of Type:" + clazz.getName());
+				
+		}		
+	}
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/IdentityLink.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/IdentityLink.java
new file mode 100644
index 00000000..becd630e
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/IdentityLink.java
@@ -0,0 +1,312 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egiz.eaaf.core.impl.idp.auth.data;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.security.PublicKey;
+
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Element;
+
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
+import at.gv.egiz.eaaf.core.impl.utils.DOMUtils;
+
+
+/**
+ * Data contained in an identity link issued by BMI, relevant to the MOA ID component.
+ * <br><code>"IdentityLink"</code> is the translation of <code>"Personenbindung"</code>.
+ * 
+ * @author Paul Ivancsics
+ * @version $Id$
+ */
+public class IdentityLink implements Serializable, IIdentityLink{
+
+	private static final long serialVersionUID = 1L;
+	
+	/**
+	 * <code>"identificationValue"</code> is the translation of <code>"Stammzahl"</code>.
+	 */
+	private String identificationValue;
+	/**
+	* <code>"identificationType"</code> type of the identificationValue in the IdentityLink.
+	*/
+	private String identificationType;
+	/**
+	 * first name
+	 */
+	private String givenName;
+	/**
+	 * family name
+	 */
+	private String familyName;
+  
+  /**
+   * The name as (givenName + familyName)
+   */
+  private String name;
+	/**
+	 * date of birth
+	 */
+	private String dateOfBirth;
+  /**
+   * the original saml:Assertion-Element
+   */
+	private Element samlAssertion;
+  /**
+   * the serializes saml:Assertion
+   */
+  private String serializedSamlAssertion;
+	/**
+	 * Element /saml:Assertion/saml:AttributeStatement/saml:Subject/saml:SubjectConfirmation/saml:SubjectConfirmationData/pr:Person
+	 */
+	private Element prPerson;
+  /**
+   * we need for each dsig:Reference Element all
+   * transformation elements
+   */
+  private Element[] dsigReferenceTransforms;
+  
+  /**
+   * The issuing time of the identity link SAML assertion.
+   */
+  private String issueInstant;
+
+  /**
+   * we need all public keys stored in 
+   * the identity link
+   */
+  private PublicKey[] publicKey;
+
+	/**
+	 * Constructor for IdentityLink
+	 */
+	public IdentityLink() {
+	}
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getDateOfBirth()
+ */
+  @Override
+public String getDateOfBirth() {
+    return dateOfBirth;
+  }
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getFamilyName()
+ */
+  @Override
+public String getFamilyName() {
+    return familyName;
+  }
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getGivenName()
+ */
+  @Override
+public String getGivenName() {
+    return givenName;
+  }
+  
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getName()
+ */
+  @Override
+public String getName() {
+    if (name == null) {
+      name = givenName + " " + familyName;
+    }
+    return name;
+  }
+  
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getIdentificationValue()
+ */
+  @Override
+public String getIdentificationValue() {
+    return identificationValue;
+  }
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getIdentificationType()
+	 */
+	@Override
+	public String getIdentificationType() {
+		return identificationType;
+	}
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setDateOfBirth(java.lang.String)
+ */
+  @Override
+public void setDateOfBirth(String dateOfBirth) {
+    this.dateOfBirth = dateOfBirth;
+  }
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setFamilyName(java.lang.String)
+ */
+  @Override
+public void setFamilyName(String familyName) {
+    this.familyName = familyName;
+  }
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setGivenName(java.lang.String)
+ */
+  @Override
+public void setGivenName(String givenName) {
+    this.givenName = givenName;
+  }
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setIdentificationValue(java.lang.String)
+ */
+  @Override
+public void setIdentificationValue(String identificationValue) {
+    this.identificationValue = identificationValue;
+  }
+  
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setIdentificationType(java.lang.String)
+	 */
+	@Override
+	public void setIdentificationType(String identificationType) {
+		this.identificationType = identificationType;
+	}
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getSamlAssertion()
+ */
+  @Override
+public Element getSamlAssertion() {
+    return samlAssertion;
+  }
+  
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getSerializedSamlAssertion()
+ */
+  @Override
+public String getSerializedSamlAssertion() {
+    return serializedSamlAssertion;
+  }
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setSamlAssertion(org.w3c.dom.Element)
+ */
+  @Override
+public void setSamlAssertion(Element samlAssertion) throws TransformerException, IOException {
+    this.samlAssertion = samlAssertion;
+    this.serializedSamlAssertion = DOMUtils.serializeNode(samlAssertion);    
+  }
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getDsigReferenceTransforms()
+ */
+  @Override
+public Element[] getDsigReferenceTransforms() {
+    return dsigReferenceTransforms;
+  }
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setDsigReferenceTransforms(org.w3c.dom.Element[])
+ */
+  @Override
+public void setDsigReferenceTransforms(Element[] dsigReferenceTransforms) {
+    this.dsigReferenceTransforms = dsigReferenceTransforms;
+  }
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getPublicKey()
+ */
+  @Override
+public PublicKey[] getPublicKey() {
+    return publicKey;
+  }
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setPublicKey(java.security.PublicKey[])
+ */
+  @Override
+public void setPublicKey(PublicKey[] publicKey) {
+    this.publicKey = publicKey;
+  }
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getPrPerson()
+ */
+  @Override
+public Element getPrPerson() {
+    return prPerson;
+  }
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setPrPerson(org.w3c.dom.Element)
+ */
+  @Override
+public void setPrPerson(Element prPerson) {
+    this.prPerson = prPerson;
+  }
+  
+   /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getIssueInstant()
+ */
+  @Override
+public String getIssueInstant() {
+    return issueInstant;
+  }
+
+  /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setIssueInstant(java.lang.String)
+ */
+  @Override
+public void setIssueInstant(String issueInstant) {
+    this.issueInstant = issueInstant;
+  }
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/SimpleIdentityLinkAssertionParser.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/SimpleIdentityLinkAssertionParser.java
new file mode 100644
index 00000000..7fb5e642
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/SimpleIdentityLinkAssertionParser.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egiz.eaaf.core.impl.idp.auth.data;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.util.Base64Utils;
+import org.w3c.dom.Element;
+import org.w3c.dom.traversal.NodeIterator;
+
+import at.gv.egiz.eaaf.core.api.data.XMLNamespaceConstants;
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
+import at.gv.egiz.eaaf.core.exceptions.EAAFParserException;
+import at.gv.egiz.eaaf.core.impl.utils.DOMUtils;
+import at.gv.egiz.eaaf.core.impl.utils.XPathUtils;
+
+/**
+ * Parses MDS from an identity link <code>&lt;saml:Assertion&gt;</code>
+ * <br>
+ * <b>This IDL parser extract NO key information!</b>
+
+ */
+public class SimpleIdentityLinkAssertionParser {
+
+  //
+  // XPath namespace prefix shortcuts
+  //
+
+  /** Xpath prefix for reaching PersonData Namespaces */
+  private static final String PDATA = XMLNamespaceConstants.PD_PREFIX + ":";
+  /** Xpath prefix for reaching SAML Namespaces */
+  private static final String SAML = XMLNamespaceConstants.SAML_PREFIX + ":";
+  /** Xpath prefix for reaching XML-DSIG Namespaces */
+  private static final String DSIG = XMLNamespaceConstants.DSIG_PREFIX + ":";
+  /** Xpath prefix for reaching ECDS Namespaces */
+  private static final String ECDSA = XMLNamespaceConstants.ECDSA_PREFIX + ":";
+  /** Xpath expression to the root element */  
+	private static final String ROOT = "";
+ /** Xpath expression to the SAMLSubjectConfirmationData element */
+  private static final String SAML_SUBJECT_CONFIRMATION_DATA_XPATH =
+      ROOT
+      + SAML
+      + "AttributeStatement/"
+      + SAML
+      + "Subject/"
+      + SAML
+      + "SubjectConfirmation/"
+      + SAML
+      + "SubjectConfirmationData";
+  /** Xpath expression to the PersonData element */
+	private static final String PERSON_XPATH =
+		SAML_SUBJECT_CONFIRMATION_DATA_XPATH
+      + "/"
+      + PDATA
+      + "Person";
+  /** Xpath expression to the PersonData GivenName element */      
+  public static final String PERSON_GIVEN_NAME_XPATH =
+    PERSON_XPATH
+    	+ "/"
+      + PDATA
+      + "Name/"
+      + PDATA
+      + "GivenName";
+  /** Xpath expression to the PersonData FamilyName element */
+  public static final String PERSON_FAMILY_NAME_XPATH =
+    PERSON_XPATH
+    	+ "/"
+      + PDATA
+      + "Name/"
+      + PDATA
+      + "FamilyName";
+  /** Xpath expression to the PersonData DateOfBirth element */
+  public static final String PERSON_DATE_OF_BIRTH_XPATH =
+    PERSON_XPATH
+    	+ "/"
+      + PDATA
+      + "DateOfBirth";
+  /** Xpath expression to the Identification element */
+  private static final String PERSON_IDENT_XPATH =
+    PERSON_XPATH
+    	+ "/"
+      + PDATA
+      + "Identification";
+
+  /** Xpath expression to the Identification Value element */	
+  public static final String PERSON_IDENT_VALUE_XPATH =
+    PERSON_XPATH
+    	+ "/"
+      + PDATA
+      + "Identification/"
+      + PDATA
+      + "Value";
+
+	/** Xpath expression to the Identification Value element */	
+	public static final String PERSON_IDENT_TYPE_XPATH =
+		PERSON_XPATH
+			+ "/"
+			+ PDATA
+			+ "Identification/"
+			+ PDATA
+			+ "Type";
+
+  /** Xpath expression to the RSAKeyValue element */
+  private static final String RSA_KEY_VALUE_XPATH =
+    ROOT
+      + SAML
+      + "AttributeStatement/"
+      + SAML
+      + "Attribute/"
+      + SAML
+      + "AttributeValue/"
+      + DSIG
+      + "RSAKeyValue";
+
+  /** Xpath expression to the ECKeyValue element */
+  private static final String ECDSA_KEY_VALUE_XPATH =
+    ROOT
+      + SAML
+      + "AttributeStatement/"
+      + SAML
+      + "Attribute/"
+      + SAML
+      + "AttributeValue/"
+      + ECDSA
+      + "ECDSAKeyValue";
+
+  
+  /** Xpath expression to the RSA Modulus element */
+  private static final String RSA_KEY_MODULUS_XPATH = DSIG + "Modulus";
+  /** Xpath expression to the RSA Exponent element */
+  private static final String RSA_KEY_EXPONENT_XPATH = DSIG + "Exponent";
+  /** Xpath expression to the DSIG X509Certificate element */
+  private static final String DSIG_CERTIFICATES_XPATH =
+    ROOT
+      + DSIG
+      + "Signature/"
+      + DSIG
+      + "KeyInfo/"
+      + DSIG
+      + "X509Data/"
+      + DSIG
+      + "X509Certificate";
+ /** Xpath expression to the DSIG Transforms element */
+ private static final String DSIG_REFERENCE_TRANSFORMATION_XPATH = 
+   ROOT 
+   + DSIG 
+   + "Signature/" 
+   + DSIG 
+   + "SignedInfo/" 
+   + DSIG 
+   + "Reference/" 
+   + DSIG 
+   + "Transforms";
+ 
+ /** The IssueInstant attribute of the SAML assertion */
+ private static final String ISSUE_INSTANT_ATTR = "IssueInstant";
+      
+  /**This is the root element of the XML-Document provided by the Security Layer Card*/
+  private Element assertionElem;
+
+  /**
+   * Constructor for <code>IdentityLinkAssertionParser</code>.
+   * A DOM-representation of the incoming String will be created
+   * @param xmlAssertion <code>&lt;saml:Assertion&gt;</code> as String
+   * @throws EAAFParserException on any parsing error
+   */
+  public SimpleIdentityLinkAssertionParser(String xmlAssertion) throws EAAFParserException {
+    try {
+      InputStream s = new ByteArrayInputStream(xmlAssertion.getBytes("UTF-8"));
+      assertionElem = DOMUtils.parseXmlValidating(s);
+      
+    }
+    catch (Throwable t) {
+      throw new EAAFParserException("parser.01", new Object[] { t.toString()},
+    		  t.getMessage(), t);
+      
+    }
+  }
+  
+  /**
+   * Sets the <@link assertionElem>.
+   * @param xmlAssertion the assertion element
+   * @throws EAAFParserException on any parsing error
+   */
+  public SimpleIdentityLinkAssertionParser(Element xmlAssertion) throws EAAFParserException {
+    assertionElem = xmlAssertion;
+  }
+
+  /**
+   * Constructor for <code>IdentityLinkAssertionParser</code>.
+   * A DOM-representation of the incoming Inputstream will be created
+   * @param xmlAssertion <code>&lt;saml:Assertion&gt;</code> as InputStream
+   * @throws EAAFParserException on any parsing error
+   */
+  public SimpleIdentityLinkAssertionParser(InputStream xmlAssertion) throws EAAFParserException {
+    try {
+      assertionElem = DOMUtils.parseXmlValidating(xmlAssertion);
+      
+    }
+    catch (Throwable t) {
+      throw new EAAFParserException("parser.01", new Object[] { t.toString() }, t.getMessage(), t);
+      
+    }
+  }
+
+  /**
+   * Parses the identity link from the <code>&lt;saml:Assertion&gt;</code>
+   * @return Identity link
+   * @throws EAAFParserException on any parsing error
+   */
+
+  public IIdentityLink parseIdentityLink() throws EAAFParserException {
+    IIdentityLink identityLink;
+    try {
+      identityLink = new IdentityLink();
+      identityLink.setSamlAssertion(assertionElem);
+      identityLink.setIssueInstant(assertionElem.getAttribute(ISSUE_INSTANT_ATTR));
+      identityLink.setPrPerson((Element)
+      	XPathUtils.selectSingleNode(assertionElem, PERSON_XPATH));
+      identityLink.setIdentificationValue(
+        XPathUtils.getElementValue(assertionElem, PERSON_IDENT_VALUE_XPATH, ""));
+			identityLink.setIdentificationType(
+				XPathUtils.getElementValue(assertionElem, PERSON_IDENT_TYPE_XPATH, ""));
+			
+	  String givenname = XPathUtils.getElementValue(assertionElem, PERSON_GIVEN_NAME_XPATH, "");
+	  String familyname = XPathUtils.getElementValue(assertionElem, PERSON_FAMILY_NAME_XPATH, "");
+
+	  // replace ' in name with &#39;
+	  givenname = givenname.replaceAll("'", "&#39;");
+	  familyname = familyname.replaceAll("'", "&#39;");			
+		
+      identityLink.setGivenName(givenname);
+      identityLink.setFamilyName(familyname);
+      identityLink.setDateOfBirth(
+        XPathUtils.getElementValue(assertionElem, PERSON_DATE_OF_BIRTH_XPATH, ""));
+			 NodeIterator dsigRefTransforms = 
+			 XPathUtils.selectNodeIterator(assertionElem, DSIG_REFERENCE_TRANSFORMATION_XPATH);
+       List transElems = new ArrayList();
+       Element transformsElem;
+       while ((transformsElem = (Element) dsigRefTransforms.nextNode()) != null) {
+          transElems.add(transformsElem);
+       }
+       Element[] result = new Element[transElems.size()];
+       transElems.toArray(result);  
+       identityLink.setDsigReferenceTransforms(result);
+       
+       //identityLink.setPublicKey(getPublicKeys());
+   
+    }
+    catch (Throwable t) {
+      throw new EAAFParserException("parser.01", new Object[] { t.toString() },
+    		  t.getMessage(), t);
+    }
+
+    return identityLink;
+  }
+
+  /**
+    * Parses a string array of decoded base64 certificates from 
+    * the <code>&lt;InfoboxReadResponse&gt;</code> found in the dsig-signature
+    * @return String[] with raw-certificates from the dsig-signature keyinfo
+    * @throws Exception
+    */
+  public String[] getCertificates() throws Exception {
+    List certs = new ArrayList();
+    NodeIterator rsaIter =
+      XPathUtils.selectNodeIterator(assertionElem, DSIG_CERTIFICATES_XPATH);
+    Element certElem;
+    while ((certElem = (Element) rsaIter.nextNode()) != null) {
+      String content = DOMUtils.getText(certElem);
+      certs.add(new String(Base64Utils.decodeFromString(content)));
+      
+    }
+    String[] result = new String[certs.size()];
+    certs.toArray(result);
+    return result;
+
+  }
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java
new file mode 100644
index 00000000..a421ff67
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.auth.modules;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileItemFactory;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.lang3.ArrayUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IRequestStorage;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractAuthProtocolModulController;
+import at.gv.egiz.eaaf.core.impl.idp.process.springweb.AbstractTask;
+import at.gv.egiz.eaaf.core.impl.utils.DataURLBuilder;
+
+/**
+ * Task based counterpart to {@link AuthServlet}, providing the same utility methods (error handling, parameter parsing
+ * etc.).</p> The code has been taken from {@link AuthServlet}.
+ */
+public abstract class AbstractAuthServletTask extends AbstractTask {
+	private static final Logger log = LoggerFactory.getLogger(AbstractAuthServletTask.class);
+	
+	@Autowired(required=true) protected IRequestStorage requestStoreage;	
+	@Autowired(required=true) protected IConfiguration authConfig;
+	
+	@Autowired protected IRevisionLogger revisionsLogger;
+	
+	protected static final String ERROR_CODE_PARAM = "errorid";
+
+	protected IRequest pendingReq = null;
+	
+	public abstract void execute(ExecutionContext executionContext, HttpServletRequest request,
+			HttpServletResponse response) throws TaskExecutionException;
+	
+	
+	protected final IRequest internalExecute(IRequest pendingReq, ExecutionContext executionContext, HttpServletRequest request,
+			HttpServletResponse response) throws TaskExecutionException {
+		//set pending-request object
+		this.pendingReq = pendingReq;
+		
+		//execute task specific action
+		execute(executionContext, request, response);
+		
+		//return pending-request object
+		return this.pendingReq;
+	}
+	
+	/**
+	 * Redirect the authentication process to protocol specific finalization endpoint.  
+	 * 
+	 * @param pendingReq Actually processed protocol specific authentication request
+	 * @param httpResp
+	 */
+	protected void performRedirectToProtocolFinialization(IRequest pendingReq, HttpServletResponse httpResp) {
+		performRedirectToItself(pendingReq, httpResp, AbstractAuthProtocolModulController.ENDPOINT_FINALIZEPROTOCOL);
+				
+	}
+	
+	/**
+	 * Redirect the authentication process to IDP itself  
+	 * 
+	 * @param pendingReq Actually processed protocol specific authentication request
+	 * @param httpResp
+	 * @param idpEndPoint Servlet EndPoint that should receive the redirect
+	 */
+	protected void performRedirectToItself(IRequest pendingReq, HttpServletResponse httpResp, String idpEndPoint) {
+		String redirectURL = new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), 
+				idpEndPoint, pendingReq.getPendingRequestId());
+						
+		httpResp.setContentType("text/html");
+		httpResp.setStatus(302);
+		httpResp.addHeader("Location", redirectURL);		
+		log.debug("REDIRECT TO: " + redirectURL); 
+		
+	}
+	
+	
+	/**
+	 * Parses the request input stream for parameters, assuming parameters are
+	 * encoded UTF-8 (no standard exists how browsers should encode them).
+	 * 
+	 * @param req
+	 *            servlet request
+	 * 
+	 * @return mapping parameter name -> value
+	 * 
+	 * @throws IOException
+	 *             if parsing request parameters fails.
+	 * 
+	 * @throws FileUploadException
+	 *             if parsing request parameters fails.
+	 */
+	protected Map<String, String> getParameters(HttpServletRequest req) throws IOException,
+			FileUploadException {
+
+		Map<String, String> parameters = new HashMap<String, String>();
+
+		if (ServletFileUpload.isMultipartContent(req)) {
+			// request is encoded as mulitpart/form-data
+			FileItemFactory factory = new DiskFileItemFactory();
+			ServletFileUpload upload = null;
+			upload = new ServletFileUpload(factory);
+			List items = null;
+			items = upload.parseRequest(req);
+			for (int i = 0; i < items.size(); i++) {
+				FileItem item = (FileItem) items.get(i);
+				if (item.isFormField()) {
+					// Process only form fields - no file upload items
+					parameters.put(item.getFieldName(), item.getString("UTF-8"));
+					
+					//log requests on trace
+					if (log.isTraceEnabled()) {
+						String logString = item.getString("UTF-8");
+
+						// TODO use RegExp
+						String startS = "<pr:Identification><pr:Value>";
+						String endS = "</pr:Value><pr:Type>urn:publicid:gv.at:baseid</pr:Type>";
+						String logWithMaskedBaseid = logString;
+						int start = logString.indexOf(startS);
+						if (start > -1) {
+							int end = logString.indexOf(endS);
+							if (end > -1) {
+								logWithMaskedBaseid = logString.substring(0, start);
+								logWithMaskedBaseid += startS;
+								logWithMaskedBaseid += "xxxxxxxxxxxxxxxxxxxxxxxx";
+								logWithMaskedBaseid += logString.substring(end,
+										logString.length());
+							}
+						}
+						
+						log.debug("Processed multipart/form-data request parameter: \nName: "
+								+ item.getFieldName()
+								+ "\nValue: "
+								+ logWithMaskedBaseid);	
+					}
+										
+				}
+			}
+		}
+
+		else {	
+			Iterator<Entry<String, String[]>> requestParamIt = req.getParameterMap().entrySet().iterator();
+			while (requestParamIt.hasNext()) {
+				Entry<String, String[]> entry = requestParamIt.next();
+				String key = entry.getKey();
+				String[] values = entry.getValue();
+				// take the last value from the value array since the legacy code above also does it this way
+				parameters.put(key, ArrayUtils.isEmpty(values) ? null : values[values.length-1]); 
+			}
+			
+		}
+
+		return parameters;
+	}
+
+	/**
+	 * Reads bytes up to a delimiter, consuming the delimiter.
+	 * 
+	 * @param in
+	 *            input stream
+	 * @param delimiter
+	 *            delimiter character
+	 * @return String constructed from the read bytes
+	 * @throws IOException
+	 */
+	protected String readBytesUpTo(InputStream in, char delimiter)
+			throws IOException {
+		ByteArrayOutputStream bout = new ByteArrayOutputStream();
+		boolean done = false;
+		int b;
+		while (!done && (b = in.read()) >= 0) {
+			if (b == delimiter)
+				done = true;
+			else
+				bout.write(b);
+		}
+		return bout.toString();
+	}
+
+	/**
+	 * Adds a parameter to a URL.
+	 * 
+	 * @param url
+	 *            the URL
+	 * @param paramname
+	 *            parameter name
+	 * @param paramvalue
+	 *            parameter value
+	 * @return the URL with parameter added
+	 */
+	protected static String addURLParameter(String url, String paramname,
+			String paramvalue) {
+		String param = paramname + "=" + paramvalue;
+		if (url.indexOf("?") < 0)
+			return url + "?" + param;
+		else
+			return url + "&" + param;
+	}
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/ModuleRegistration.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/ModuleRegistration.java
new file mode 100644
index 00000000..cb4a055a
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/ModuleRegistration.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.auth.modules;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.io.Resource;
+
+import at.gv.egiz.eaaf.core.api.idp.auth.modules.AuthModule;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
+import at.gv.egiz.eaaf.core.impl.idp.process.ProcessDefinitionParserException;
+
+/**
+ * This class handles registering modules. The modules are detected either with
+ * the ServiceLoader mechanism or via Spring. All detected modules are ranked
+ * according to their priority.
+ */
+public class ModuleRegistration {
+
+	private static ModuleRegistration instance = new ModuleRegistration();
+
+	private List<AuthModule> priorizedModules = new ArrayList<>();
+
+	@Autowired
+	private ApplicationContext ctx;
+
+	@Autowired
+	private ProcessEngine processEngine;
+
+	private Logger log = LoggerFactory.getLogger(getClass());
+
+	public static ModuleRegistration getInstance() {
+		return instance;
+	}
+
+	private ModuleRegistration() {
+	}
+
+	@PostConstruct
+	private void init() {
+		// load modules via the ServiceLoader
+		initServiceLoaderModules();
+
+		// load modules via Spring
+		initSpringModules();
+
+		// order modules according to their priority
+		sortModules();
+	}
+	
+	/**
+	 * Discovers modules which use the ServiceLoader mechanism.
+	 */
+	private void initServiceLoaderModules() {
+		log.info("Looking for auth modules.");
+		ServiceLoader<AuthModule> loader = ServiceLoader.load(AuthModule.class);
+		Iterator<AuthModule> modules = loader.iterator();
+		while (modules.hasNext()) {
+			AuthModule module = modules.next();
+			log.info("Detected module {}", module.getClass().getName());
+			registerModuleProcessDefinitions(module);
+			priorizedModules.add(module);
+		}
+	}
+
+	/**
+	 * Discovers modules which use Spring.
+	 */
+	private void initSpringModules() {
+		log.debug("Discovering Spring modules.");
+		Map<String, AuthModule> modules = ctx.getBeansOfType(AuthModule.class);
+		for (AuthModule module : modules.values()) {
+			registerModuleProcessDefinitions(module);
+			priorizedModules.add(module);
+		}
+	}
+
+	/**
+	 * Registers the resource uris for the module.
+	 * 
+	 * @param module
+	 *            the module.
+	 */
+	private void registerModuleProcessDefinitions(AuthModule module) {
+		for (String uri : module.getProcessDefinitions()) {
+			Resource resource = ctx.getResource(uri);
+			if (resource.isReadable()) {
+				log.info("Registering process definition '{}'.", uri);
+				try (InputStream processDefinitionInputStream = resource.getInputStream()) {
+					processEngine.registerProcessDefinition(processDefinitionInputStream);
+				} catch (IOException e) {
+					log.error("Process definition '{}' could NOT be read.", uri, e);
+				} catch (ProcessDefinitionParserException e) {
+					log.error("Error while parsing process definition '{}'", uri, e);
+				}
+			} else {
+				log.error("Process definition '{}' cannot be read.", uri);
+			}
+		}
+	}
+
+	/**
+	 * Order the modules in descending order according to their priority.
+	 */
+	private void sortModules() {
+		Collections.sort(priorizedModules, new Comparator<AuthModule>() {
+			@Override
+			public int compare(AuthModule thisAuthModule, AuthModule otherAuthModule) {
+				int thisOrder = thisAuthModule.getPriority();
+				int otherOrder = otherAuthModule.getPriority();
+				return (thisOrder < otherOrder ? 1 : (thisOrder == otherOrder ? 0 : -1));
+			}
+		});
+	}
+
+	/**
+	 * Returns the process description id of the first process, in the highest ranked
+	 * module, which is able to work with the given execution context.
+	 * 
+	 * @param context
+	 *            the {@link ExecutionContext}.
+	 * @return the process id or {@code null}
+	 */
+	public String selectProcess(ExecutionContext context) {
+		for (AuthModule module : priorizedModules) {
+			String id = module.selectProcess(context);
+			if (StringUtils.isNotEmpty(id)) {
+				log.debug("Process with id '{}' selected, for context '{}'.", id, context);
+				return id;
+			}
+		}
+		log.info("No process is able to handle context '{}'.", context);
+		return null;
+	}
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BPKAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BPKAttributeBuilder.java
new file mode 100644
index 00000000..575f2beb
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BPKAttributeBuilder.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IPVPAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException;
+
+public class BPKAttributeBuilder implements IPVPAttributeBuilder {
+	
+	private static final Logger log = LoggerFactory.getLogger(BPKAttributeBuilder.class);
+	
+	public String getName() {
+		return BPK_NAME;
+	}
+	
+	public <ATT> ATT build(ISPConfiguration oaParam, IAuthData authData,
+			IAttributeGenerator<ATT> g) throws AttributeBuilderException {
+		String bpk = authData.getBPK();
+		String type = authData.getBPKType();
+		
+		if (StringUtils.isEmpty(bpk))
+			throw new UnavailableAttributeException(BPK_NAME);
+			
+		if (type.startsWith(EAAFConstants.URN_PREFIX_WBPK))
+			type = type.substring((EAAFConstants.URN_PREFIX_WBPK).length());
+		
+		else if (type.startsWith(EAAFConstants.URN_PREFIX_CDID)) 
+			type = type.substring((EAAFConstants.URN_PREFIX_CDID).length());
+		
+		else if (type.startsWith(EAAFConstants.URN_PREFIX_EIDAS)) 
+			type = type.substring((EAAFConstants.URN_PREFIX_EIDAS).length());
+		
+		if (bpk.length() > BPK_MAX_LENGTH) {
+			bpk = bpk.substring(0, BPK_MAX_LENGTH);
+		}
+		
+		log.trace("Authenticate user with bPK/wbPK " + bpk + " and Type=" + type);
+		
+		return g.buildStringAttribute(BPK_FRIENDLY_NAME, BPK_NAME, type + ":" + bpk);
+	}
+	
+	public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+		return g.buildEmptyAttribute(BPK_FRIENDLY_NAME, BPK_NAME);
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BirthdateAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BirthdateAttributeBuilder.java
new file mode 100644
index 00000000..cac7e3bf
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BirthdateAttributeBuilder.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IPVPAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+
+public class BirthdateAttributeBuilder implements IPVPAttributeBuilder {
+		
+	public String getName() {
+		return BIRTHDATE_NAME;
+	}
+	
+	public <ATT> ATT build(ISPConfiguration oaParam, IAuthData authData,
+			IAttributeGenerator<ATT> g) throws AttributeBuilderException {
+		
+		if (authData.getDateOfBirth() != null) {			
+			DateFormat pvpDateFormat = new SimpleDateFormat(BIRTHDATE_FORMAT_PATTERN);
+			String dateString = pvpDateFormat.format(authData.getDateOfBirth());
+		
+			return g.buildStringAttribute(BIRTHDATE_FRIENDLY_NAME, BIRTHDATE_NAME, dateString);
+			
+		} else {
+			//build empty attribute if no Birthday date is found (STORK2)
+			return g.buildEmptyAttribute(BIRTHDATE_FRIENDLY_NAME, BIRTHDATE_NAME);
+			
+		}
+	}
+	
+	public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+		return g.buildEmptyAttribute(BIRTHDATE_FRIENDLY_NAME, BIRTHDATE_NAME);
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDIdentityLinkBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDIdentityLinkBuilder.java
new file mode 100644
index 00000000..f55353d2
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDIdentityLinkBuilder.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+import java.io.IOException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.Base64Utils;
+
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IPVPAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException;
+
+
+
+public class EIDIdentityLinkBuilder implements IPVPAttributeBuilder {
+	private static final Logger log = LoggerFactory.getLogger(EIDIdentityLinkBuilder.class);
+	
+	
+	public String getName() {
+		return EID_IDENTITY_LINK_NAME;
+	}
+
+	public <ATT> ATT build(ISPConfiguration oaParam, IAuthData authData,
+			IAttributeGenerator<ATT> g) throws AttributeBuilderException {
+		try {
+			String ilAssertion = null;			
+			if (authData.getIdentityLink() == null)
+				throw new UnavailableAttributeException(EID_IDENTITY_LINK_NAME);
+			
+			ilAssertion = authData.getIdentityLink().getSerializedSamlAssertion();
+			
+			return g.buildStringAttribute(EID_IDENTITY_LINK_FRIENDLY_NAME,
+					EID_IDENTITY_LINK_NAME, Base64Utils.encodeToString(ilAssertion.getBytes("UTF-8")));
+			
+			
+		} catch (IOException e) {
+			log.warn("IdentityLink serialization error.", e);
+			return g.buildEmptyAttribute(EID_IDENTITY_LINK_FRIENDLY_NAME,
+					EID_IDENTITY_LINK_NAME);
+		}
+		
+	}
+
+	public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+		return g.buildEmptyAttribute(EID_IDENTITY_LINK_FRIENDLY_NAME,
+				EID_IDENTITY_LINK_NAME);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDIssuingNationAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDIssuingNationAttributeBuilder.java
new file mode 100644
index 00000000..9a038aa2
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDIssuingNationAttributeBuilder.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IPVPAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+
+public class EIDIssuingNationAttributeBuilder implements IPVPAttributeBuilder {
+
+	public String getName() {
+		return EID_ISSUING_NATION_NAME;
+	}
+
+	public <ATT> ATT build(ISPConfiguration oaParam, IAuthData authData,
+			IAttributeGenerator<ATT> g) throws AttributeBuilderException {
+		String countryCode = authData.getCiticenCountryCode();
+		if (StringUtils.isNotEmpty(countryCode))
+			return g.buildStringAttribute(EID_ISSUING_NATION_FRIENDLY_NAME,
+					EID_ISSUING_NATION_NAME, countryCode);
+		
+		else
+			return null;
+	}
+
+	public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+		return g.buildEmptyAttribute(EID_ISSUING_NATION_FRIENDLY_NAME,
+				EID_ISSUING_NATION_NAME);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDSectorForIDAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDSectorForIDAttributeBuilder.java
new file mode 100644
index 00000000..c170a124
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDSectorForIDAttributeBuilder.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IPVPAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException;
+
+public class EIDSectorForIDAttributeBuilder implements IPVPAttributeBuilder {
+
+	public String getName() {
+		return EID_SECTOR_FOR_IDENTIFIER_NAME;
+	}
+
+	public <ATT> ATT build(ISPConfiguration oaParam, IAuthData authData,
+			IAttributeGenerator<ATT> g) throws AttributeBuilderException {		
+		String bpktype = authData.getBPKType();
+		
+		if (StringUtils.isEmpty(authData.getBPKType()))
+			throw new UnavailableAttributeException(EID_SECTOR_FOR_IDENTIFIER_NAME);
+				
+		return g.buildStringAttribute(EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME,
+				EID_SECTOR_FOR_IDENTIFIER_NAME, bpktype);
+	}
+	
+	public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+		return g.buildEmptyAttribute(EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME,
+				EID_SECTOR_FOR_IDENTIFIER_NAME);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDSourcePIN.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDSourcePIN.java
new file mode 100644
index 00000000..52654f86
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDSourcePIN.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IPVPAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+import at.gv.egiz.eaaf.core.exceptions.AttributePolicyException;
+import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException;
+
+public class EIDSourcePIN implements IPVPAttributeBuilder  {
+
+	public String getName() {
+		return EID_SOURCE_PIN_NAME;
+	}
+
+	public <ATT> ATT build(ISPConfiguration oaParam, IAuthData authData,
+			IAttributeGenerator<ATT> g) throws AttributeBuilderException {
+		
+		if (authData.isBaseIDTransferRestrication())
+			throw new AttributePolicyException(EID_SOURCE_PIN_NAME);
+		
+		else {
+			if (StringUtils.isNoneEmpty(authData.getIdentificationValue()))
+				throw new UnavailableAttributeException(EID_SOURCE_PIN_NAME);
+			
+			return g.buildStringAttribute(EID_SOURCE_PIN_FRIENDLY_NAME, EID_SOURCE_PIN_NAME, authData.getIdentificationValue());
+		}
+	}
+
+	public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+		return g.buildEmptyAttribute(EID_SOURCE_PIN_FRIENDLY_NAME, EID_SOURCE_PIN_NAME);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDSourcePINType.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDSourcePINType.java
new file mode 100644
index 00000000..ef2d8e82
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDSourcePINType.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IPVPAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException;
+
+public class EIDSourcePINType implements IPVPAttributeBuilder {
+
+	public String getName() {
+		return EID_SOURCE_PIN_TYPE_NAME;
+	}
+	
+	public <ATT> ATT build(ISPConfiguration oaParam, IAuthData authData,
+			IAttributeGenerator<ATT> g) throws AttributeBuilderException {
+		
+		if (authData.isBaseIDTransferRestrication())
+			throw new UnavailableAttributeException(EID_SOURCE_PIN_TYPE_NAME);
+		
+		else {
+			return g.buildStringAttribute(EID_SOURCE_PIN_TYPE_FRIENDLY_NAME, EID_SOURCE_PIN_TYPE_NAME, authData.getIdentificationType());
+		}
+	}
+
+	public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+		return g.buildEmptyAttribute(EID_SOURCE_PIN_TYPE_FRIENDLY_NAME, EID_SOURCE_PIN_TYPE_NAME);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDeIDASQAALevelAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDeIDASQAALevelAttributeBuilder.java
new file mode 100644
index 00000000..213faeb8
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EIDeIDASQAALevelAttributeBuilder.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IPVPAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+
+public class EIDeIDASQAALevelAttributeBuilder implements IPVPAttributeBuilder {
+
+	public String getName() {
+		return EID_CITIZEN_EIDAS_QAA_LEVEL_NAME;
+	}
+
+	public <ATT> ATT build(ISPConfiguration oaParam, IAuthData authData,
+			IAttributeGenerator<ATT> g) throws AttributeBuilderException {
+		
+		return g.buildStringAttribute(EID_CITIZEN_EIDAS_QAA_LEVEL_FRIENDLY_NAME, 
+				EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, authData.getEIDASQAALevel());
+	}
+	
+	
+	public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+		return g.buildEmptyAttribute(EID_CITIZEN_EIDAS_QAA_LEVEL_FRIENDLY_NAME, 
+				EID_CITIZEN_EIDAS_QAA_LEVEL_NAME);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/GivenNameAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/GivenNameAttributeBuilder.java
new file mode 100644
index 00000000..083adb36
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/GivenNameAttributeBuilder.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IPVPAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+
+public class GivenNameAttributeBuilder implements IPVPAttributeBuilder {
+
+	public String getName() {
+		return GIVEN_NAME_NAME;
+	}
+
+	public <ATT> ATT build(ISPConfiguration oaParam, IAuthData authData,
+			IAttributeGenerator<ATT> g) throws AttributeBuilderException {
+		return g.buildStringAttribute(GIVEN_NAME_FRIENDLY_NAME, GIVEN_NAME_NAME, authData.getGivenName());
+	}
+	
+	public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+		return g.buildEmptyAttribute(GIVEN_NAME_FRIENDLY_NAME, GIVEN_NAME_NAME);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/PVPVersionAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/PVPVersionAttributeBuilder.java
new file mode 100644
index 00000000..006f9854
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/PVPVersionAttributeBuilder.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IPVPAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+
+public class PVPVersionAttributeBuilder implements IPVPAttributeBuilder {
+	
+	public String getName() {
+		return PVP_VERSION_NAME;
+	}
+	
+	public <ATT> ATT build(ISPConfiguration oaParam, IAuthData authData,
+			IAttributeGenerator<ATT> g) throws AttributeBuilderException {
+		return g.buildStringAttribute(PVP_VERSION_FRIENDLY_NAME, PVP_VERSION_NAME, PVP_VERSION_2_1);
+	}
+	
+	public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+		return g.buildEmptyAttribute(PVP_VERSION_FRIENDLY_NAME, PVP_VERSION_NAME);
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/PrincipalNameAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/PrincipalNameAttributeBuilder.java
new file mode 100644
index 00000000..8828a022
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/PrincipalNameAttributeBuilder.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IPVPAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+
+public class PrincipalNameAttributeBuilder implements IPVPAttributeBuilder {
+	
+	public String getName() {
+		return PRINCIPAL_NAME_NAME;
+	}
+	
+	public <ATT> ATT build(ISPConfiguration oaParam, IAuthData authData,
+			IAttributeGenerator<ATT> g) throws AttributeBuilderException {
+		return g.buildStringAttribute(PRINCIPAL_NAME_FRIENDLY_NAME, PRINCIPAL_NAME_NAME, authData.getFamilyName());
+	}
+	
+	public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+		return g.buildEmptyAttribute(PRINCIPAL_NAME_FRIENDLY_NAME, PRINCIPAL_NAME_NAME);
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/AbstractConfigurationImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/AbstractConfigurationImpl.java
new file mode 100644
index 00000000..2b868b16
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/AbstractConfigurationImpl.java
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.conf;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+
+public abstract class AbstractConfigurationImpl implements IConfiguration {
+	private static final Logger log = LoggerFactory.getLogger(AbstractConfigurationImpl.class);
+	
+	private static final String URI_SCHEME_CLASSPATH = "classpath";
+	private static final String URI_SCHEME_FILESYSTEM = "file";
+	
+	private final URI internalConfigPath;
+	private final URI configRootDirectory;
+	private final Properties properties;
+	
+	public AbstractConfigurationImpl(final String configPath) throws EAAFConfigurationException {
+		InputStream is = null;
+		try {
+			log.debug("Starting EAAFCore initialization process .... ");
+			
+			if (StringUtils.isEmpty(configPath)) {
+				log.debug("Primary configuration is empty. Search for backup configuration .... ");
+				internalConfigPath = new URI(getBackupConfigPath());
+							
+			} else
+				internalConfigPath = new URI(configPath);
+									
+			log.info("Load EAAFCore configuration from " + internalConfigPath);
+			
+			
+			//extract configuration root directory
+			//TODO: check if it works with classpath
+			File propertiesFile = new File(internalConfigPath);
+			String configDir = propertiesFile.getParent();
+			configRootDirectory = new File(configDir).toURI();			
+			log.debug("Set EAAFCore configuration root directory to " + configRootDirectory.toString());
+			
+			
+			//get input stream from configuration path 			
+			if (internalConfigPath.getScheme().equals(URI_SCHEME_FILESYSTEM)) {
+				log.trace("Load config from filesystem");
+				is = new FileInputStream(propertiesFile);
+				
+			} else if (internalConfigPath.getScheme().equals(URI_SCHEME_CLASSPATH)) {
+				log.trace("Load config from classpath");
+				is = this.getClass().getResourceAsStream(internalConfigPath.toString());
+				
+			} else {
+				log.error("Can not load EAAFCore configuration. Unsupported prefix! (Only 'file:' and 'classpath:')  ");
+				throw new EAAFConfigurationException("Can not load EAAFCore configuration. Unsupported prefix");
+				
+			}
+			
+			if (is == null) {
+				log.error("Can NOT load EAAFCore configuration from file " +  internalConfigPath.toString());
+				throw new EAAFConfigurationException("Can NOT load EAAFCore configuration from file " + internalConfigPath.toString());
+				
+			}
+			
+			
+			//load EAAF core configuration into properties object
+			properties = new Properties();
+			properties.load(is);
+			
+			log.info("EAAFCore configuration loaded");
+			
+			
+		} catch (URISyntaxException | IOException e) {
+			log.error("Can not parse configuration path " + configPath + " or " + getBackupConfigPath());
+			throw new EAAFConfigurationException("Can not parse configuration path", e);
+			
+		} finally {
+			if (is != null) {
+				try {
+					is.close();
+					
+				} catch (IOException e) {
+					log.warn("Can not close inputstream from configuration loader!");
+					
+				}
+			}
+		}
+		
+	}
+	
+	@Override
+	public String getBasicConfiguration(String key) {
+		if (StringUtils.isNotEmpty(key)) {
+			String value = properties.getProperty(addPrefixToKey(key));
+			if (value != null)
+				return value.trim();
+		}
+		
+		return null;
+	}
+
+	@Override
+	public String getBasicConfiguration(String key, String defaultValue) {
+		if (StringUtils.isNotEmpty(key)) {
+			String value = properties.getProperty(addPrefixToKey(key), defaultValue);
+			if (value != null)
+				return value.trim();
+		}
+		
+		return defaultValue;
+	}
+
+	@Override
+	public Map<String, String> getBasicMOAIDConfigurationWithPrefix(String prefix) {
+		return KeyValueUtils.getSubSetWithPrefix(KeyValueUtils.convertPropertiesToMap(properties), addPrefixToKey(prefix));
+		
+	}
+
+	@Override
+	public boolean getBasicMOAIDConfigurationBoolean(String key, boolean defaultValue) {
+		String value = getBasicConfiguration(key);		
+		if (StringUtils.isNotEmpty(value))
+			return Boolean.valueOf(value.trim());
+						
+		return defaultValue;
+		
+	}
+	
+	@Override
+	public Properties getFullConfigurationProperties() {
+		return properties;
+		
+	}
+
+	@Override
+	public URI getConfigurationRootDirectory() {
+		return configRootDirectory;
+		
+	}
+	
+	@Override
+	public URI getConfigurationFilePath() {
+		return internalConfigPath;
+		
+	}
+	
+	/**
+	 * Get the path to backup configuration
+	 * 
+	 * @return A filepath file: or a classpath classpath:
+	 */
+	abstract protected String getBackupConfigPath();
+	
+	/**
+	 * Get a specific configuration-key prefix for this software implementation
+	 * 
+	 * @return
+	 */
+	abstract public String getApplicationSpecificKeyPrefix();
+
+	
+	private String addPrefixToKey(String key) {
+		if (StringUtils.isNotEmpty(getApplicationSpecificKeyPrefix())) {
+			if (getApplicationSpecificKeyPrefix().endsWith(KeyValueUtils.KEY_DELIMITER))
+				return getApplicationSpecificKeyPrefix() + key;
+			else
+				return getApplicationSpecificKeyPrefix() + KeyValueUtils.KEY_DELIMITER + key;
+			
+		}
+		
+		return key;
+		
+	}
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/SPConfigurationImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/SPConfigurationImpl.java
new file mode 100644
index 00000000..e402983d
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/SPConfigurationImpl.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.conf;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.api.data.EAAFConfigConstants;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+
+public class SPConfigurationImpl implements ISPConfiguration {
+	private static final long serialVersionUID = 688541755446463453L;
+
+	private static final Logger log = LoggerFactory.getLogger(SPConfigurationImpl.class);
+	
+	private final Map<String, String> spConfiguration;
+	private final List<String> targetAreasWithNoInteralBaseIdRestriction;
+	private final List<String> targetAreasWithNoBaseIdTransmissionRestriction;	
+	
+	
+	public SPConfigurationImpl(final Map<String, String> spConfig, IConfiguration authConfig) {	  
+		  this.spConfiguration = spConfig;
+		  
+		  //set oa specific restrictions
+		  targetAreasWithNoInteralBaseIdRestriction = Collections.unmodifiableList(
+				  	KeyValueUtils.getListOfCSVValues(
+				  			authConfig.getBasicConfiguration(
+				  					CONFIG_KEY_RESTRICTIONS_BASEID_INTERNAL, 
+				  					EAAFConstants.URN_PREFIX_CDID)));
+		  
+		  targetAreasWithNoBaseIdTransmissionRestriction = Collections.unmodifiableList(
+				  	KeyValueUtils.getListOfCSVValues(
+				  			authConfig.getBasicConfiguration(
+				  					CONFIG_KEY_RESTRICTIONS_BASEID_TRANSMISSION, 
+				  					EAAFConstants.URN_PREFIX_CDID)));
+		  
+		  if (log.isTraceEnabled()) {
+			  log.trace("Internal policy for OA: " + getUniqueIdentifier());
+			  for (String el : targetAreasWithNoInteralBaseIdRestriction)
+				  log.trace(" Allow baseID processing for prefix " + el);		  
+			  for (String el : targetAreasWithNoBaseIdTransmissionRestriction)
+				  log.trace(" Allow baseID transfer for prefix " + el);
+			  		  
+		  }
+	  }
+	
+	
+	@Override
+	public final Map<String, String> getFullConfiguration() {
+		return this.spConfiguration;
+		
+	}
+
+	@Override
+	public final String getConfigurationValue(String key) {
+		if (key == null)
+			return null;
+		else
+			return this.spConfiguration.get(key);
+		
+	}
+
+	@Override
+	public final String getConfigurationValue(String key, String defaultValue) {
+		String value = getConfigurationValue(key);
+		if (value == null)
+			return defaultValue;
+		else 
+			return value;
+	}
+
+
+	@Override
+	public final Boolean isConfigurationValue(String key) {
+		String value = getConfigurationValue(key);
+		if (value != null) {
+			return Boolean.parseBoolean(value);
+			
+		}
+		
+		return null;
+	}
+
+
+	@Override
+	public final boolean isConfigurationValue(String key, boolean defaultValue) {
+		String value = getConfigurationValue(key);
+		if (value != null) {
+			return Boolean.parseBoolean(value);
+			
+		}
+		
+		return defaultValue;
+	}
+	
+	@Override
+	public final boolean containsConfigurationKey(String key) {
+		if (key == null)
+			return false;
+		else
+			return this.spConfiguration.containsKey(key);
+		
+	}
+	
+	@Override
+	public String getUniqueIdentifier() {
+		return getConfigurationValue(EAAFConfigConstants.SERVICE_UNIQUEIDENTIFIER);
+		
+	}
+
+	@Override
+	public boolean hasBaseIdInternalProcessingRestriction() {
+		  return false;
+		  
+	}
+
+	@Override
+	public boolean hasBaseIdTransferRestriction() {	  
+		return true;
+		  
+	}
+
+
+	@Override
+	public final List<String> getTargetsWithNoBaseIdInternalProcessingRestriction() {
+		return this.targetAreasWithNoInteralBaseIdRestriction;
+	}
+
+
+	@Override
+	public final List<String> getTargetsWithNoBaseIdTransferRestriction() {
+		return this.targetAreasWithNoBaseIdTransmissionRestriction;
+	}
+
+
+	@Override
+	public String getMinimumLevelOfAssurence() {
+		log.warn("Method not implemented: " + SPConfigurationImpl.class.getName() + " 'getMinimumLevelOfAssurence()'");
+		return null;
+	}
+
+
+	@Override
+	public String getAreaSpecificTargetIdentifier() {
+		log.warn("Method not implemented: " + SPConfigurationImpl.class.getName() + " 'getAreaSpecificTargetIdentifier()'");
+		return null;
+	}
+
+
+	@Override
+	public String getFriendlyName() {
+		log.warn("Method not implemented: " + SPConfigurationImpl.class.getName() + " 'getFriendlyName()'");
+		return null;
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractAuthProtocolModulController.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractAuthProtocolModulController.java
new file mode 100644
index 00000000..d72ee404
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractAuthProtocolModulController.java
@@ -0,0 +1,225 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.controller;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.gv.egiz.components.eventlog.api.EventConstants;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IStatusMessager;
+import at.gv.egiz.eaaf.core.api.idp.IAction;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IAuthenticationDataBuilder;
+import at.gv.egiz.eaaf.core.api.idp.IModulInfo;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.auth.IAuthenticationManager;
+import at.gv.egiz.eaaf.core.api.idp.auth.ISSOManager;
+import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface;
+import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFSSOException;
+
+/**
+ * @author tlenz
+ *
+ */
+
+public abstract class AbstractAuthProtocolModulController extends AbstractController {
+	private static final Logger log = LoggerFactory.getLogger(AbstractAuthProtocolModulController.class);
+	
+	public static final String ENDPOINT_FINALIZEPROTOCOL = "finalizeAuthProtocol";	
+	public static final String ENDPOINT_ERRORHANDLING = "errorHandling";
+		
+	 
+	@Autowired(required=true) private IAuthenticationManager authmanager;			
+	@Autowired(required=true) private IAuthenticationDataBuilder authDataBuilder;
+	@Autowired(required=false) private ISSOManager ssoManager;
+	
+	/**
+	 * Initialize an authentication process for this protocol request
+	 * 
+	 * @param httpReq HttpServletRequest	
+	 * @param httpResp HttpServletResponse
+	 * @param protocolRequest Authentication request which is actually in process
+	 * @throws IOException 
+	 */
+	protected void performAuthentication(HttpServletRequest req, HttpServletResponse resp, 
+			IRequest pendingReq) throws IOException {
+		try {
+			if (pendingReq.isNeedAuthentication()) {
+				//request needs authentication --> start authentication process ...
+			
+				//load Parameters from OnlineApplicationConfiguration
+				ISPConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
+				
+				if (oaParam == null)
+					throw new EAAFAuthenticationException(
+							IStatusMessager.CODES_INTERNAL_ERROR_AUTH_NOSPCONFIG, 
+							new Object[] { pendingReq.getSPEntityId() }, 
+							"No Service Provider configuration found.");
+									
+				if (authmanager.doAuthentication(req, resp, pendingReq)) {					
+					//pending request is already authenticated --> protocol-specific postProcessing can start directly 					
+					finalizeAuthenticationProcess(req, resp, pendingReq);
+					
+					//transaction is finished, log transaction finished event
+					revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED, pendingReq.getUniqueTransactionIdentifier());
+					
+				}
+							
+			} else {			
+				executeProtocolSpecificAction(req, resp, pendingReq, null);
+			
+			}
+			
+		} catch (Exception e) {
+			buildProtocolSpecificErrorResponse(e, req, resp, pendingReq);			
+			authmanager.performOnlyIDPLogOut(req, resp, pendingReq);
+						
+		}		
+	}
+	
+	
+	/**
+	 * Finalize the requested protocol operation
+	 * 
+	 * @param httpReq HttpServletRequest	
+	 * @param httpResp HttpServletResponse
+	 * @param protocolRequest Authentication request which is actually in process
+	 * @param moaSession MOASession object, which is used to generate the protocol specific authentication information
+	 * @throws Exception 
+	 */
+	protected void finalizeAuthenticationProcess(HttpServletRequest req, HttpServletResponse resp, 
+			IRequest pendingReq) throws Exception {
+		
+		String newSSOSessionId = null;
+		
+		//if Single Sign-On functionality is enabled for this request
+		if (pendingReq.needSingleSignOnFunctionality()) {
+			if (ssoManager != null)
+				newSSOSessionId = ssoManager.createNewSSOSessionCookie(req, resp, pendingReq);
+			else
+				log.warn("SSO is requested but there is not SSO Session-Manager available");
+			
+		}
+		
+		//build authenticationdata from session information and OA configuration
+		IAuthData authData = authDataBuilder.buildAuthenticationData(pendingReq);	
+			
+		//execute the protocol-specific action
+		SLOInformationInterface sloInformation = executeProtocolSpecificAction(req, resp, pendingReq, authData);
+				
+		//Store OA specific SSO session information if an SSO cookie is set
+		if (StringUtils.isNotEmpty(newSSOSessionId)) { 		
+			try {
+				//create new SSO session, if actually no SSO session exists
+				if (StringUtils.isEmpty(pendingReq.getSSOSessionIdentifier())) {
+					ssoManager.createNewSSOSession(pendingReq, newSSOSessionId, sloInformation);
+									
+					//MOA SSO-session already exists only update is required
+				} else {
+					ssoManager.updateSSOSession(pendingReq, newSSOSessionId, sloInformation);
+					
+					
+				} 
+											
+			} catch (EAAFSSOException e) {
+				log.warn("SSO Session information can not be stored  -> SSO is not enabled!");				
+				authmanager.performOnlyIDPLogOut(req, resp, pendingReq);
+				
+			}
+		
+		} else {
+			//remove MOASession from database
+			authmanager.performOnlyIDPLogOut(req, resp, pendingReq);
+			
+		}
+	
+		//Advanced statistic logging
+		statisticLogger.logSuccessOperation(pendingReq, authData, StringUtils.isNotEmpty(newSSOSessionId));
+				
+	}
+	
+	/**
+	 * Executes the requested protocol action
+	 * 
+	 * @param httpReq HttpServletRequest	
+	 * @param httpResp HttpServletResponse
+	 * @param protocolRequest Authentication request which is actually in process
+	 * @param authData Service-provider specific authentication data
+	 * 
+	 * @return Return Single LogOut information or null if protocol supports no SSO
+	 * 
+	 * @throws Exception 
+	 */
+	private SLOInformationInterface executeProtocolSpecificAction(HttpServletRequest httpReq, HttpServletResponse httpResp, 
+			IRequest pendingReq, IAuthData authData) throws Exception {
+		try {
+		//	request needs no authentication --> start request processing
+			Class<?> clazz = Class.forName(pendingReq.requestedAction());
+			if (clazz == null || 
+					!IAction.class.isAssignableFrom(clazz)) {
+				log.error("Requested protocol-action processing Class is NULL or does not implement the IAction interface.");
+				throw new Exception("Requested protocol-action processing Class is NULL or does not implement the IAction interface.");
+				
+			}
+			
+			IAction protocolAction = (IAction) applicationContext.getBean(clazz);			 
+			return protocolAction.processRequest(pendingReq, httpReq, httpResp, authData);
+			
+		} catch (ClassNotFoundException e) {
+			log.error("Requested Auth. protocol processing Class is NULL or does not implement the IAction interface.");
+			throw new Exception("Requested Auth. protocol processing Class is NULL or does not implement the IAction interface.");
+		}
+		
+	}
+		
+	protected void buildProtocolSpecificErrorResponse(Throwable throwable, HttpServletRequest req, 
+			HttpServletResponse resp, IRequest protocolRequest) throws IOException {
+		try {
+			
+			Class<?> clazz = Class.forName(protocolRequest.requestedModule());
+			
+			if (clazz == null || 
+					!IModulInfo.class.isAssignableFrom(clazz)) {
+				log.error("Requested protocol module Class is NULL or does not implement the IModulInfo interface.");
+				throw new Exception("Requested protocol module Class is NULL or does not implement the IModulInfo interface.");
+				
+			}
+							
+			IModulInfo handlingModule = (IModulInfo) applicationContext.getBean(clazz);
+												
+			if (handlingModule.generateErrorMessage(
+					throwable, req, resp, protocolRequest)) {
+		
+				//log Error to technical log
+				logExceptionToTechnicalLog(throwable);
+				
+				//log Error Message
+				statisticLogger.logErrorOperation(throwable, protocolRequest);
+				
+				//write revision log entries
+				revisionsLogger.logEvent(protocolRequest, EventConstants.TRANSACTION_ERROR, protocolRequest.getUniqueTransactionIdentifier());
+				
+				return;
+				
+			} else {
+				handleErrorNoRedirect(throwable, req, resp, true);
+				
+			}
+			
+		} catch (Throwable e) {
+			handleErrorNoRedirect(throwable, req, resp, true);
+			
+		}
+		
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java
new file mode 100644
index 00000000..980d77ba
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java
@@ -0,0 +1,354 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.controller;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.naming.ConfigurationException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+import at.gv.egiz.components.eventlog.api.EventConstants;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IRequestStorage;
+import at.gv.egiz.eaaf.core.api.IStatusMessager;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.data.ExceptionContainer;
+import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfiguration;
+import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfigurationFactory;
+import at.gv.egiz.eaaf.core.api.gui.IGUIFormBuilder;
+import at.gv.egiz.eaaf.core.api.gui.ModifyableGuiBuilderConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
+import at.gv.egiz.eaaf.core.api.logging.IStatisticLogger;
+import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
+import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.GUIBuildException;
+import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException;
+import at.gv.egiz.eaaf.core.exceptions.ProcessExecutionException;
+import at.gv.egiz.eaaf.core.exceptions.ProtocolNotActiveException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.utils.HTTPUtils;
+import at.gv.egiz.eaaf.core.impl.utils.Random;
+import at.gv.egiz.eaaf.core.impl.utils.ServletUtils;
+
+
+/**
+ * @author tlenz
+ *
+ */
+public abstract class AbstractController {
+
+	private static final Logger log = LoggerFactory.getLogger(AbstractController.class);
+
+	@Autowired(required=true) protected ApplicationContext applicationContext;	
+	@Autowired(required=true) protected IConfiguration authConfig;
+	@Autowired(required=true) protected ITransactionStorage transactionStorage;
+	@Autowired(required=true) protected IRequestStorage requestStorage;
+	@Autowired(required=true) protected IGUIFormBuilder guiBuilder;
+	@Autowired(required=true) protected IGUIBuilderConfigurationFactory guiConfigFactory;
+	@Autowired(required=true) protected IStatusMessager statusMessager;
+	
+	@Autowired protected IStatisticLogger statisticLogger;
+	@Autowired protected IRevisionLogger revisionsLogger;
+	
+	
+	
+	
+	
+	@ExceptionHandler({EAAFException.class})
+	public void MOAIDExceptionHandler(HttpServletRequest req, HttpServletResponse resp, Exception e) throws IOException {				
+		log.error(e.getMessage() , e);
+		internalMOAIDExceptionHandler(req, resp, e, true);
+		
+	}
+	
+	@ExceptionHandler({Exception.class})
+	public void GenericExceptionHandler(HttpServletResponse resp, Exception exception) throws IOException {
+		log.error("Internel Server Error." , exception);
+		resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);		
+		resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error!" +
+				"(Errorcode=9199"
+				+" | Description=" 
+				+ StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(exception.getMessage())) 
+				+ ")");
+		return;
+		
+	}
+	
+	@ExceptionHandler({IOException.class})
+	public void IOExceptionHandler(HttpServletResponse resp, Throwable exception) {
+		log.error("Internel Server Error." , exception);
+		resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
+		resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+		return;
+		
+	}
+	
+	protected void handleError(String errorMessage, Throwable exceptionThrown,
+			HttpServletRequest req, HttpServletResponse resp, IRequest pendingReq) throws IOException {
+
+		String pendingRequestID = null;
+		if (pendingReq != null)
+			pendingRequestID = pendingReq.getPendingRequestId();
+		
+		Throwable loggedException = null;
+		Throwable extractedException = extractOriginalExceptionFromProcessException(exceptionThrown);
+		
+		//extract pendingRequestID and originalException if it was a TaskExecutionException
+		if (extractedException instanceof TaskExecutionException) {
+			//set original exception
+			loggedException = ((TaskExecutionException) extractedException).getOriginalException();
+			
+			//use TaskExecutionException directly, if no Original Exeception is included
+			if (loggedException == null)
+				loggedException = exceptionThrown;
+			
+			//set pending-request ID if it is set
+			String reqID = ((TaskExecutionException) extractedException).getPendingRequestID();
+			if (StringUtils.isNotEmpty(reqID))
+				pendingRequestID = reqID; 
+						
+		} else
+			loggedException = exceptionThrown;
+					
+		try {			
+			//switch to protocol-finalize method to generate a protocol-specific error message
+
+			//log error directly in debug mode
+			if (log.isDebugEnabled())
+				log.warn(loggedException.getMessage(), loggedException);
+				
+			
+			//put exception into transaction store for redirect
+			String key = Random.nextLongRandom();
+			if (pendingReq != null) {
+				revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR);
+				transactionStorage.put(key, 
+						new ExceptionContainer(pendingReq, loggedException), -1);
+			
+			} else {
+				transactionStorage.put(key, 
+						new ExceptionContainer(null, loggedException), -1);
+				
+			}
+			
+			//build up redirect URL
+			String redirectURL = null;
+			redirectURL = ServletUtils.getBaseUrl(req);	
+			redirectURL += "/"+AbstractAuthProtocolModulController.ENDPOINT_ERRORHANDLING 
+					+ "?" + EAAFConstants.PARAM_HTTP_ERROR_CODE + "=" + key;
+									
+//			//only add pending-request Id if it exists 
+//			if (StringUtils.isNotEmpty(pendingRequestID))							
+//				redirectURL += "&" + EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID + "=" + pendingRequestID;
+
+			resp.setContentType("text/html");
+			resp.setStatus(302);
+
+			resp.addHeader("Location", redirectURL);		
+			log.debug("REDIRECT TO: " + redirectURL);	
+
+			return;
+					
+		} catch (Exception e) {
+			log.warn("Default error-handling FAILED. Exception can not be stored ....", e);
+			log.info("Switch to generic generic backup error-handling ... ");
+			handleErrorNoRedirect(loggedException, req, resp, true);
+			
+		}
+
+	}
+		
+	/**
+	 * Handles all exceptions with no pending request.
+	 * Therefore, the error is written to the users browser
+	 * 
+	 * @param throwable
+	 * @param req
+	 * @param resp
+	 * @throws IOException 
+	 */
+	protected void handleErrorNoRedirect(Throwable throwable, HttpServletRequest req, 
+			HttpServletResponse resp, boolean writeExceptionToStatisticLog) throws IOException {
+		
+		//log Exception into statistic database
+		if (writeExceptionToStatisticLog)
+			statisticLogger.logErrorOperation(throwable);
+		
+		//write errror to console
+		logExceptionToTechnicalLog(throwable);
+		
+		//return error to Web browser
+		if (throwable instanceof EAAFException || throwable instanceof ProcessExecutionException)
+			internalMOAIDExceptionHandler(req, resp, (Exception)throwable, false);
+		
+		else {
+			//write generic message for general exceptions
+			String msg = statusMessager.getMessage(IStatusMessager.CODES_INTERNAL_ERROR_GENERIC, null);			
+			writeHTMLErrorResponse(req, resp, msg, "9199", (Exception) throwable);
+			
+		}
+			
+	}
+	
+	/**
+	 * Write a Exception to the MOA-ID-Auth internal technical log
+	 * 
+	 * @param loggedException Exception to log
+	 */	
+	protected void logExceptionToTechnicalLog(Throwable loggedException) {
+		if (!( loggedException instanceof EAAFException 
+				 || loggedException instanceof ProcessExecutionException )) {
+			log.error("Receive an internal error: Message=" + loggedException.getMessage(), loggedException);
+	
+		} else {
+			if (log.isDebugEnabled() || log.isTraceEnabled()) {
+				log.warn(loggedException.getMessage(), loggedException);
+	
+			} else {
+				log.warn(loggedException.getMessage());
+	
+			}			
+		}		
+	}
+		
+	private void writeBadRequestErrorResponse(HttpServletRequest req, HttpServletResponse resp, EAAFException e) throws IOException {
+		String code = statusMessager.mapInternalErrorToExternalError(((InvalidProtocolRequestException)e).getErrorId());
+		String descr = StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(e.getMessage()));
+		resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
+		resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Protocol validation FAILED!" +
+				"(Errorcode=" + code +
+				" | Description=" + descr + ")");
+		
+	}
+	
+	private void writeHTMLErrorResponse(HttpServletRequest req, HttpServletResponse httpResp, String msg, String errorCode, Exception error) throws IOException {
+
+		try {
+			IGUIBuilderConfiguration config 
+				= guiConfigFactory.getDefaultErrorGUI(HTTPUtils.extractAuthURLFromRequest(req));
+
+//				HTTPUtils.extractAuthURLFromRequest(req), 
+//					DefaultGUIFormBuilderConfiguration.VIEW_ERRORMESSAGE, 
+//					null);
+				
+			//add errorcode and errormessage
+			if (config instanceof ModifyableGuiBuilderConfiguration) {
+				((ModifyableGuiBuilderConfiguration)config).putCustomParameter("errorMsg", msg);
+				((ModifyableGuiBuilderConfiguration)config).putCustomParameter("errorCode", errorCode);
+				
+				//add stacktrace if debug is enabled
+				if (log.isTraceEnabled()) {
+					((ModifyableGuiBuilderConfiguration)config).putCustomParameter("stacktrace", getStacktraceFromException(error));
+				
+				}
+				
+			} else 
+				log.info("Can not ADD error message, because 'GUIBuilderConfiguration' is not modifieable ");
+		
+			
+			
+			guiBuilder.build(httpResp, config, "Error-Message");
+			
+		} catch (GUIBuildException e) {
+			log.warn("Can not build error-message GUI.", e);
+			GenericExceptionHandler(httpResp, e);
+			
+		}
+		
+	}
+	
+	private void writeHTMLErrorResponse(HttpServletRequest req, HttpServletResponse httpResp, Exception error) throws IOException {				
+		writeHTMLErrorResponse(req, httpResp, 
+				error.getMessage(), 
+				statusMessager.getResponseErrorCode(error), 
+				error);		
+	}
+	
+	
+	private String getStacktraceFromException(Exception ex) {
+		StringWriter errors = new StringWriter();
+	    ex.printStackTrace(new PrintWriter(errors));
+	    return errors.toString();
+	    
+	}
+		
+	/**
+	 * Extracts a TaskExecutionException of a ProcessExecutionExeception Stacktrace.
+	 * 
+	 * @param exception 
+	 * @return Return the latest TaskExecutionExecption if exists, otherwise the latest ProcessExecutionException
+	 */
+	private Throwable extractOriginalExceptionFromProcessException(Throwable exception) {
+		Throwable exholder = exception;
+		TaskExecutionException taskExc = null;
+		
+		while(exholder != null 
+				&& exholder instanceof ProcessExecutionException) {
+			ProcessExecutionException procExc = (ProcessExecutionException) exholder;
+			if (procExc.getCause() != null && 
+					procExc.getCause() instanceof TaskExecutionException) {
+				taskExc = (TaskExecutionException) procExc.getCause();
+				exholder = taskExc.getOriginalException();
+			
+			} else
+				break;
+			
+		}
+				
+		if (taskExc == null)
+			return exholder;
+		
+		else
+			return taskExc;
+	}
+	
+	private void internalMOAIDExceptionHandler(HttpServletRequest req, HttpServletResponse resp, Exception e, boolean writeExceptionToStatisicLog) throws IOException {				
+		if (e instanceof ProtocolNotActiveException) {
+			resp.getWriter().write(e.getMessage());
+			resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
+			resp.sendError(HttpServletResponse.SC_FORBIDDEN, 
+					StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(e.getMessage())));
+		
+		} else if (e instanceof AuthnRequestValidatorException) {
+			AuthnRequestValidatorException ex = (AuthnRequestValidatorException)e;
+			//log Error Message
+			if (writeExceptionToStatisicLog)
+				statisticLogger.logErrorOperation(ex, ex.getErrorRequest());
+			
+			//write error message
+			writeBadRequestErrorResponse(req, resp, (EAAFException) e);			
+		
+		} else if (e instanceof InvalidProtocolRequestException) {		
+			//send error response
+			writeBadRequestErrorResponse(req, resp, (EAAFException) e);
+			
+		} else if (e instanceof ConfigurationException) {
+			//send HTML formated error message
+			writeHTMLErrorResponse(req, resp, (EAAFException) e);
+		
+		} else if (e instanceof EAAFException) {
+			//send HTML formated error message
+			writeHTMLErrorResponse(req, resp, e);
+					
+		} else if (e instanceof ProcessExecutionException) {
+			//send HTML formated error message
+			writeHTMLErrorResponse(req, resp, e);
+					
+		}
+		
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java
new file mode 100644
index 00000000..a4a86ca2
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.controller;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.text.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IStatusMessager;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFIllegalStateException;
+import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils;
+
+/**
+ * Servlet that resumes a suspended process (in case of asynchronous tasks).
+ * 
+ * @author tknall
+ * 
+ */
+public abstract class AbstractProcessEngineSignalController extends AbstractController {
+	private static final Logger log = LoggerFactory.getLogger(AbstractProcessEngineSignalController.class);	
+	
+	@Autowired protected ProcessEngine processEngine;
+	
+	protected void signalProcessManagement(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+		String pendingRequestID = StringEscapeUtils.escapeHtml4(getPendingRequestId(req));
+		IRequest pendingReq = null;
+		try {	
+			if (pendingRequestID == null) {
+				new EAAFException(
+						IStatusMessager.CODES_INTERNAL_ERROR_AUTH_NOPENDIGREQID, 
+						null, 
+						"NO PendingRequestId found" 
+					);
+				
+			}
+			
+			pendingReq = requestStorage.getPendingRequest(pendingRequestID);
+			if (pendingReq == null) {
+				log.info("No PendingRequest with Id: " + pendingRequestID + " Maybe, a transaction timeout occure.");
+				throw new EAAFException(IStatusMessager.CODES_INTERNAL_ERROR_AUTH_TIMEOUT, new Object[]{pendingRequestID},
+						"No PendingRequest with Id: \" + pendingRequestID + \" Maybe, a transaction timeout occure.\"");
+				
+			}
+			
+			//change pending-request ID
+			requestStorage.changePendingRequestID(pendingReq);
+			pendingRequestID = pendingReq.getPendingRequestId();
+						
+			// process instance is mandatory
+			if (pendingReq.getProcessInstanceId() == null) {
+				throw new EAAFIllegalStateException(new Object[]{"MOA session does not provide process instance id."},
+						"No execution environemnt found for this pending request");
+				
+			}
+
+			// wake up next task
+			processEngine.signal(pendingReq);
+			
+		} catch (Exception ex) {		
+			handleError(null, ex, req, resp, pendingReq);
+			
+		} finally {
+			//MOASessionDBUtils.closeSession();
+			TransactionIDUtils.removeAllLoggingVariables();
+			
+		}
+		
+		
+	}
+	
+	/**
+	 * Retrieves the current pending-request id from the HttpServletRequest parameter
+	 * 
+	 * <p/>
+	 * Note that this class/method can be overwritten by modules providing their own strategy of retrieving the
+	 * respective pending-request id.
+	 * 
+	 * @param request
+	 *            The unterlying HttpServletRequest.
+	 * @return The current pending-request id.
+	 */
+	public String getPendingRequestId(HttpServletRequest request) {
+		return StringEscapeUtils.escapeHtml4(request.getParameter(EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID));
+		
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java
new file mode 100644
index 00000000..3659ff4f
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.controller;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.text.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import at.gv.egiz.components.eventlog.api.EventConstants;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IStatusMessager;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.data.ExceptionContainer;
+import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+
+/**
+ * @author tlenz
+ *
+ */
+@Controller
+public class ProtocolFinalizationController extends AbstractAuthProtocolModulController {
+	private static final Logger log = LoggerFactory.getLogger(ProtocolFinalizationController.class);
+	
+	@RequestMapping(value = ENDPOINT_ERRORHANDLING, method = {RequestMethod.GET})
+	public void errorHandling(HttpServletRequest req, HttpServletResponse resp) throws EAAFException, IOException {
+		//receive an authentication error
+		String errorid = StringEscapeUtils.escapeHtml4(req.getParameter(EAAFConstants.PARAM_HTTP_ERROR_CODE));
+		if (errorid != null) {
+			IRequest pendingReq = null;
+			try {				
+				//load stored exception from database
+				ExceptionContainer container = transactionStorage.get(errorid, ExceptionContainer.class);								
+				if (container != null) {					
+					//remove exception if it was found
+					transactionStorage.remove(errorid);
+					
+					Throwable throwable = container.getExceptionThrown();
+					pendingReq = container.getPendingRequest();
+					
+					if (pendingReq != null) {													
+						//build protocol-specific error message if possible
+						buildProtocolSpecificErrorResponse(throwable, req, resp, pendingReq);
+																
+						//remove active user-session
+						transactionStorage.remove(pendingReq.getPendingRequestId());
+	
+						return;
+	
+					} else {
+						handleErrorNoRedirect(throwable, req, resp, true);
+	
+					}
+				} else {
+					handleErrorNoRedirect(
+							new EAAFException(
+									IStatusMessager.CODES_INTERNAL_ERROR_AUTH_NOPENDIGREQID, 
+									null, 
+									"NO Error with this Id found" 
+								), req, resp, false);
+					
+				}
+				
+			} catch (Throwable e) {
+				log.error(e.getMessage(), e);				
+				handleErrorNoRedirect(e, req, resp, false);
+			
+			} finally {
+				//remove pending-request
+				if (pendingReq != null) {
+					requestStorage.removePendingRequest(pendingReq.getPendingRequestId());
+					revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED, pendingReq.getUniqueTransactionIdentifier());
+					
+				}
+				
+			}
+			
+		} else {
+			log.debug("Request contains NO ErrorId");
+			handleErrorNoRedirect(
+					new EAAFException(
+							IStatusMessager.CODES_INTERNAL_ERROR_AUTH_NOPENDIGREQID, 
+							null, 
+							"Request containts NO error id." 
+						), req, resp, false);
+			
+		}
+		
+	}
+	
+	
+	@RequestMapping(value = ENDPOINT_FINALIZEPROTOCOL, method = {RequestMethod.GET})
+	public void finalizeAuthProtocol(HttpServletRequest req, HttpServletResponse resp) throws EAAFException, IOException {
+		
+		//read pendingRequest from http request
+		Object idObject = StringEscapeUtils.escapeHtml4(req.getParameter(EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID));
+		IRequest pendingReq = null;
+		String pendingRequestID = null;
+		if (idObject != null && (idObject instanceof String)) {
+			pendingRequestID = (String) idObject;
+			pendingReq = requestStorage.getPendingRequest(pendingRequestID);
+			
+		}
+ 						
+		if (pendingReq == null) {
+			log.error("No PendingRequest with ID " + pendingRequestID + " found.!");		
+			handleErrorNoRedirect(
+					new EAAFException(
+							IStatusMessager.CODES_INTERNAL_ERROR_AUTH_TIMEOUT, 
+							new Object[]{pendingRequestID,
+							},
+								"No pendigReq with Id: " + pendingRequestID), req, resp, false);							
+			
+		} else {
+			try {
+				log.debug("Finalize PendingRequest with ID " + pendingRequestID);
+							
+				//check if pending-request has 'abortedByUser' flag set
+				if (pendingReq.isAbortedByUser()) {
+					//send authentication aborted error to Service Provider
+					buildProtocolSpecificErrorResponse(
+							new EAAFAuthenticationException(
+									IStatusMessager.CODES_INTERNAL_ERROR_AUTH_USERSTOP, 
+									new Object[] {},
+									"User stops authentication process"), 
+							req, resp, pendingReq);
+					
+					//do not remove the full active SSO-Session 
+					// in case of only one Service-Provider authentication request is aborted   
+					if ( !pendingReq.needSingleSignOnFunctionality())  {
+						transactionStorage.remove(pendingReq.getPendingRequestId());
+						
+					}							
+
+					//check if pending-request are authenticated					
+				} else if (pendingReq.isAuthenticated()) {				
+					finalizeAuthenticationProcess(req, resp, pendingReq);
+
+				} else {
+					//suspect state: pending-request is not aborted but also are not authenticated 
+					log.error("PendingRequest is NOT authenticated --> Abort authentication process!");		
+					handleErrorNoRedirect(
+							new EAAFException(
+									"auth.20",
+									null,
+									"PendingRequest is NOT authenticated --> Abort authentication process!"
+								), req, resp, true);							
+									
+				}
+							
+			} catch (Exception e) {
+				log.error("Finalize authentication protocol FAILED." , e);
+				buildProtocolSpecificErrorResponse(e, req, resp, pendingReq);
+				
+				if (pendingReq != null)
+					transactionStorage.remove(pendingReq.getPendingRequestId());
+				
+			}		
+		}
+		
+		//remove pending-request
+		if (pendingReq != null) {
+			requestStorage.removePendingRequest(pendingReq.getPendingRequestId());
+			revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED, pendingReq.getUniqueTransactionIdentifier());
+			
+		}
+		
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java
new file mode 100644
index 00000000..6a7f4440
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java
@@ -0,0 +1,386 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.controller.protocols;
+
+import java.io.Serializable;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.naming.ConfigurationException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException;
+import at.gv.egiz.eaaf.core.impl.utils.HTTPUtils;
+import at.gv.egiz.eaaf.core.impl.utils.Random;
+import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils;
+
+public abstract class RequestImpl implements IRequest, Serializable{
+		
+	private static final Logger log = LoggerFactory.getLogger(RequestImpl.class);
+	
+	public static final String DATAID_REQUESTER_IP_ADDRESS = "reqestImpl_requesterIPAddr";
+	
+	private static final long serialVersionUID = 1L;
+
+	private String module = null;
+	private String action = null;
+	
+	private String pendingRequestId;
+	private String processInstanceId;
+	private String ssoSessionId;
+	
+	private String uniqueTransactionIdentifer;
+	private String uniqueSessionIdentifer;
+	
+	private String requestedServiceProviderIdentifer;
+	private String idpAuthURL = null;
+
+	private ISPConfiguration spConfiguration = null;
+	
+	private boolean passiv = false;
+	private boolean force = false;
+	private boolean isAbortedByUser = false;
+	
+	//every request needs authentication by default
+	private boolean needAuthentication = true;
+	
+	//every request is not authenticated by default
+	private boolean isAuthenticated = false;
+	
+	//every request needs no SSO by default
+	private boolean needSSO = false;
+	 
+	private boolean needUserConsent = false;
+	
+	private Map<String, Object> genericDataStorage = new HashMap<String, Object>();
+
+	
+			 	
+	/**
+	 * @throws ConfigurationException 
+	 * 
+	 */
+	public final void initialize(HttpServletRequest req, IConfiguration authConfig) throws EAAFException {				
+		//set pendingRequestId
+		pendingRequestId = Random.nextLongRandom();
+				
+		//set unique transaction identifier for logging
+		uniqueTransactionIdentifer = Random.nextLongRandom();		
+		TransactionIDUtils.setTransactionId(uniqueTransactionIdentifer);
+		
+		//initialize session object
+		genericDataStorage.put(EAAFConstants.AUTH_DATA_CREATED, new Date());
+		//genericDataStorage.put(EAAFConstants.VALUE_SESSIONID, Random.nextLongRandom());
+		
+		//check if End-Point is valid		
+		String authURLString = HTTPUtils.extractAuthURLFromRequest(req);
+		URL authReqURL;
+		try {
+			authReqURL = new URL(authURLString);
+			
+		} catch (MalformedURLException e) {
+			log.error("IDP AuthenticationServiceURL Prefix is not a valid URL." + authURLString, e);
+			throw new EAAFAuthenticationException("errorId", new Object[]{authURLString}, 
+					"IDP AuthenticationServiceURL Prefix is not a valid URL.",  e);
+			
+		}
+		this.idpAuthURL = authConfig.validateIDPURL(authReqURL);
+		if (this.idpAuthURL == null) {
+			log.warn("Extract AuthenticationServiceURL: " + authReqURL + " is NOT found in configuration.");
+			throw new EAAFAuthenticationException("errorId", new Object[]{authURLString}, 
+					"Extract AuthenticationServiceURL: " + authReqURL + " is NOT found in configuration.");
+			
+		}
+		
+		//set unique session identifier
+		String uniqueID = (String) req.getAttribute(EAAFConstants.UNIQUESESSIONIDENTIFIER);
+		if (StringUtils.isNotEmpty(uniqueID))
+			this.uniqueSessionIdentifer = uniqueID;		
+		
+		else {
+			log.debug("Create new sessionIdentifier for this pendingRequest ... ");
+			this.uniqueSessionIdentifer = Random.nextLongRandom();
+			
+		}
+		
+		//set requester's IP address
+		try {
+			setGenericDataToSession(DATAID_REQUESTER_IP_ADDRESS, req.getRemoteAddr());
+			
+		} catch (EAAFStorageException e) {
+			log.info("Can NOT store remote IP address into 'pendingRequest'." , e);
+			
+		}
+						
+	}
+	
+//	/**
+//	 * This method map the protocol specific requested attributes to PVP 2.1 attributes.
+//	 * 
+//	 * @return List of PVP 2.1 attribute names with maps all protocol specific attributes
+//	 */
+//	public abstract Collection<String> getRequestedAttributes(MetadataProvider metadataProvider);
+	
+	public final void setSPEntityId(String spIdentifier) {
+		this.requestedServiceProviderIdentifer = spIdentifier;
+	}
+	
+	public final String getSPEntityId() {
+		return this.requestedServiceProviderIdentifer;
+	}
+
+	public final boolean isPassiv() {
+		return passiv;
+	}
+
+	public final boolean forceAuth() {
+		return force;
+	}
+
+	public final void setPassiv(boolean passiv) {
+		this.passiv = passiv;
+	}
+
+	public final void setForce(boolean force) {
+		this.force = force;
+	}
+
+	public final String requestedAction() {
+		return action;
+	}
+
+	public final void setAction(String action) {
+		this.action = action;
+	}
+	
+	public final String requestedModule() {
+		return module;
+	}
+
+	public final void setModule(String module) {
+		this.module = module;
+	}
+
+	public final void setPendingRequestId(String pendingReqId) {
+		this.pendingRequestId = pendingReqId;
+		
+	}
+
+	public final String getPendingRequestId() {
+		return pendingRequestId;
+	}
+	
+	public final String getSSOSessionIdentifier() {
+		return this.ssoSessionId;
+	}
+	
+	public final void setSSOSessionIdentifier(String internalSSOSessionId) {
+		this.ssoSessionId = internalSSOSessionId;
+		
+	}
+	
+	public final Map<String, Object> genericFullDataStorage() {
+		return this.genericDataStorage;
+		
+	}
+	
+	public  final ISPConfiguration getServiceProviderConfiguration() {
+		return this.spConfiguration;
+		
+	
+	}
+	
+	public <T> T getServiceProviderConfiguration(final Class<T> decorator) {
+		if (this.spConfiguration != null) {
+			if (decorator.isAssignableFrom(this.spConfiguration.getClass())) {
+				return (T) this.spConfiguration;
+				
+			} else
+				log.error("Can not decorate SP configuration by '" + decorator.getName() + "'.");
+				throw new RuntimeException("Can not decorate SP configuration by '" + decorator.getName() + "'.");
+			
+		}
+		
+		return null;
+		
+	}
+	
+	public void setOnlineApplicationConfiguration(ISPConfiguration  spConfig) {
+		this.spConfiguration = spConfig;
+		
+	}
+
+	public final String getUniqueTransactionIdentifier() {
+		return this.uniqueTransactionIdentifer;
+		
+	}
+	
+	public final String getUniqueSessionIdentifier() {
+		return this.uniqueSessionIdentifer;
+		
+	}
+	
+	public final String getProcessInstanceId() {
+		return this.processInstanceId;
+		
+	}
+	
+	public final void setUniqueTransactionIdentifier(String id) {
+		this.uniqueTransactionIdentifer = id;
+		
+	}
+	
+	public final void setUniqueSessionIdentifier(String id) {
+		this.uniqueSessionIdentifer = id;
+		
+	}
+	
+	public void setProcessInstanceId(String id) {
+		this.processInstanceId = id;
+		
+	}
+	
+	public final String getAuthURL() {
+		return this.idpAuthURL;
+	}
+	
+	public final String getAuthURLWithOutSlash() {
+		if (this.idpAuthURL.endsWith("/"))
+			return this.idpAuthURL.substring(0, this.idpAuthURL.length()-1);
+		else
+			return this.idpAuthURL;
+		
+	}
+
+	public final boolean isNeedAuthentication() {
+		return needAuthentication;
+	}
+
+	public final void setNeedAuthentication(boolean needAuthentication) {
+		this.needAuthentication = needAuthentication;
+	}
+
+	public final boolean isAuthenticated() {
+		return isAuthenticated;
+	}
+
+	public final void setAuthenticated(boolean isAuthenticated) {
+		this.isAuthenticated = isAuthenticated;
+	}
+
+	public final boolean needSingleSignOnFunctionality() {
+		return needSSO;
+	}
+	public final void setNeedSingleSignOnFunctionality(boolean needSSO) {
+		this.needSSO = needSSO;
+		
+	}
+	
+	public final boolean isNeedUserConsent() {
+		return this.needUserConsent;
+		
+	}
+	
+	public final void setNeedUserConsent(boolean needConsent) {
+		this.needUserConsent = needConsent;
+		
+	}
+	
+	public final boolean isAbortedByUser() {
+		return this.isAbortedByUser;
+	}
+
+	public final void setAbortedByUser(boolean isAborted) {
+		this.isAbortedByUser = isAborted;
+		
+	}
+	
+	public final Object getGenericData(String key) {
+		if (StringUtils.isNotEmpty(key)) {
+			return genericDataStorage.get(key);
+			
+		} 
+		
+		log.info("Can not load generic request-data with key='null'");
+		return null;		
+	}
+	
+	public final <T> T getGenericData(String key, final Class<T> clazz) {
+		if (StringUtils.isNotEmpty(key)) {
+			Object data =  genericDataStorage.get(key);
+			
+			if (data == null)
+				return null;
+			
+			try {
+				@SuppressWarnings("unchecked")
+				T test = (T) data;
+				return test;
+				
+			} catch (Exception e) {
+				log.warn("Generic request-data object can not be casted to requested type", e);
+				return null;
+				
+			}
+			
+		} 
+		
+		log.info("Can not load generic request-data with key='null'");
+		return null;
+		
+	}
+	
+	@Override
+	public final void setGenericDataToSession(String key, Object object) throws EAAFStorageException {
+		if (StringUtils.isEmpty(key)) {
+			log.info("Generic request-data can not be stored with a 'null' key");
+			throw new EAAFStorageException("Generic request-data can not be stored with a 'null' key", null);
+			
+		}
+		
+		if (object != null) {
+			if (!Serializable.class.isInstance(object)) {
+				log.warn("Generic request-data can only store objects which implements the 'Seralizable' interface");
+				throw new EAAFStorageException("Generic request-data can only store objects which implements the 'Seralizable' interface", null);
+				
+			}						
+		}
+		
+		if (genericDataStorage.containsKey(key))
+			log.trace("Overwrite generic request-data with key:" + key);
+		else
+			log.trace("Add generic request-data with key:" + key + " to session.");
+		
+		genericDataStorage.put(key, object);
+		
+	}
+	
+	@Override
+	public final void setGenericDataToSession(Map<String, Object> map) throws EAAFStorageException {
+		if (map == null) {
+			log.info("Generic request-data can not be stored with a 'null' map");
+			throw new EAAFStorageException("Generic request-data can not be stored with a 'null' map", null);
+			
+		}
+		
+		//validate and store values
+		for (Entry<String, Object> el : map.entrySet())
+			setGenericDataToSession(el.getKey(), el.getValue());
+					
+	}
+		
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/FinalizeAuthenticationTask.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/FinalizeAuthenticationTask.java
new file mode 100644
index 00000000..4ab63503
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/FinalizeAuthenticationTask.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.controller.tasks;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
+
+/**
+ * @author tlenz
+ *
+ */
+@Component("FinalizeAuthenticationTask")
+public class FinalizeAuthenticationTask extends AbstractAuthServletTask {
+
+		private static final Logger log = LoggerFactory.getLogger(FinalizeAuthenticationTask.class);
+	
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+	 */
+	@Override
+	public void execute(ExecutionContext executionContext,
+			HttpServletRequest request, HttpServletResponse response)
+			throws TaskExecutionException {
+		
+		try {							
+			//set pending request to authenticated 
+			pendingReq.setAuthenticated(true);
+			requestStoreage.storePendingRequest(pendingReq);
+		
+			log.info("AuthProcess finished. Redirect to Protocol Dispatcher.");			
+			performRedirectToProtocolFinialization(pendingReq, response);
+						
+		} catch (EAAFException e) {			
+			throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+			
+		} catch (Exception e) {
+			log.warn("FinalizeAuthenticationTask has an internal error", e);
+			throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+			
+		} finally {
+			executionContext.remove(EAAFConstants.PROCESS_ENGINE_PENDINGREQUESTID);
+			
+		}
+	
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/RestartAuthProzessManagement.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/RestartAuthProzessManagement.java
new file mode 100644
index 00000000..2e5f49ed
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/RestartAuthProzessManagement.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.controller.tasks;
+
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
+import at.gv.egiz.eaaf.core.impl.idp.auth.modules.ModuleRegistration;
+import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
+import at.gv.egiz.eaaf.core.impl.idp.process.ExecutionContextImpl;
+
+/**
+ * @author tlenz
+ *
+ */
+@Component("RestartAuthProzessManagement")
+public class RestartAuthProzessManagement  extends AbstractAuthServletTask {
+	private static final Logger log = LoggerFactory.getLogger(RestartAuthProzessManagement.class);
+	
+	@Autowired ProcessEngine processEngine;
+	
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+	 */
+	@Override
+	public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
+			throws TaskExecutionException {
+		try {			
+			//create a new execution context and copy all elements to new context
+			ExecutionContext newec = new ExecutionContextImpl(); 
+			Set<String> entries = executionContext.keySet();
+			for (String key : entries) {
+				newec.put(key, executionContext.get(key));
+				
+			}
+			
+			log.debug("Select new auth.-process and restart restart process-engine ... ");
+			
+			// select and create new process instance
+			String processDefinitionId = ModuleRegistration.getInstance().selectProcess(newec);
+			if (processDefinitionId == null) {
+				log.warn("No suitable authentication process found for SessionID " + pendingReq.getPendingRequestId());
+				throw new EAAFException("process.02", new Object[] { pendingReq.getPendingRequestId()},
+				"No suitable authentication process found for SessionID \" + pendingReq.getPendingRequestId()");
+			}			
+			
+			String processInstanceId = processEngine.createProcessInstance(processDefinitionId, newec);
+
+			// keep process instance id in moa session
+			((RequestImpl)pendingReq).setProcessInstanceId(processInstanceId);
+
+			// make sure pending request has been persisted before running the process
+			try {
+				requestStoreage.storePendingRequest(pendingReq);
+				
+			} catch (EAAFException e) {
+				log.error("Database Error! MOASession is not stored!");
+				throw new EAAFException("init.04", new Object[] { pendingReq.getPendingRequestId() },
+						"Database Error! MOASession is not stored!");
+				
+			}
+			
+			log.info("Restart process-engine with auth.process:" + processDefinitionId);
+			
+			// start process
+			processEngine.start(pendingReq);
+			
+			
+		} catch (EAAFException e) {
+			throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+			
+		} catch (Exception e) {
+			log.warn("RestartAuthProzessManagement has an internal error", e);
+			throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+			
+		}			
+		
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExecutionContextImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExecutionContextImpl.java
new file mode 100644
index 00000000..05fe030d
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExecutionContextImpl.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+
+/**
+ * ExecutionContext implementation, related to a certain process instance.
+ * 
+ * @author tknall
+ * 
+ */
+public class ExecutionContextImpl implements ExecutionContext {
+
+	private static final long serialVersionUID = 1L;
+
+	private Map<String, Serializable> ctxData = Collections.synchronizedMap(new HashMap<String, Serializable>());
+
+	private String processInstanceId;
+
+	/**
+	 * Creates a new instance.
+	 */
+	public ExecutionContextImpl() {
+	}
+
+	/**
+	 * Creates a new instance and associated it with a certain process instance.
+	 */
+	public ExecutionContextImpl(String processInstanceId) {
+		this.processInstanceId = processInstanceId;
+	}
+
+	@Override
+	public void setProcessInstanceId(String processInstanceId) {
+		this.processInstanceId = processInstanceId;
+	}
+
+	@Override
+	public String getProcessInstanceId() {
+		return processInstanceId;
+	}
+
+	@Override
+	public Serializable get(String key) {
+		return ctxData.get(key);
+	}
+
+	@Override
+	public Serializable remove(String key) {
+		return ctxData.remove(key);
+	}
+
+	@Override
+	public void put(String key, Serializable object) {
+		ctxData.put(key, object);
+	}
+
+	@Override
+	public Set<String> keySet() {
+		return Collections.unmodifiableSet(ctxData.keySet());
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("ExecutionContextImpl [");
+		builder.append("id=").append(processInstanceId);
+		builder.append(", variables=");
+		builder.append(ctxData.keySet());
+		builder.append("]");
+		return builder.toString();
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExpressionEvaluationContextImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExpressionEvaluationContextImpl.java
new file mode 100644
index 00000000..5a85487f
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExpressionEvaluationContextImpl.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluationContext;
+
+/**
+ * Context implementation used for expression evaluation only.
+ * 
+ * @author tknall
+ * 
+ */
+public class ExpressionEvaluationContextImpl implements ExpressionEvaluationContext {
+
+	private static final long serialVersionUID = 1L;
+
+	private Map<String, Serializable> ctxData;
+
+	/**
+	 * Creates a new instance and initializes it with data from a given process instance.
+	 * 
+	 * @param processInstance
+	 *            The process instance.
+	 */
+	ExpressionEvaluationContextImpl(ProcessInstance processInstance) {
+		ExecutionContext executionContext = processInstance.getExecutionContext();
+		Set<String> keys = executionContext.keySet();
+		ctxData = Collections.synchronizedMap(new HashMap<String, Serializable>(keys.size()));
+		for (String key : keys) {
+			ctxData.put(key, executionContext.get(key));
+		}
+	}
+
+	@Override
+	public Map<String, Serializable> getCtx() {
+		return Collections.unmodifiableMap(ctxData);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java
new file mode 100644
index 00000000..2c715b94
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import javax.xml.stream.util.EventReaderDelegate;
+import javax.xml.transform.stax.StAXSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+import at.gv.egiz.eaaf.core.impl.idp.process.model.EndEvent;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.ProcessDefinition;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.ProcessNode;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.StartEvent;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.TaskInfo;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.Transition;
+
+/**
+ * Parses an XML representation of a process definition as defined by the respective XML schema.
+ * <p/
+ * The parser is thread-safe.
+ * @author tknall
+ *
+ */
+public class ProcessDefinitionParser {
+	
+	private static final String NS = "http://reference.e-government.gv.at/namespace/moa/process/definition/v1";
+	
+	private static Logger log = LoggerFactory.getLogger(ProcessDefinitionParser.class);
+
+	private static class LazyProcessDefinitionSchemaHolder {
+		private static final Schema PD_SCHEMA_INSTANCE;
+		static {
+			try (InputStream in = ProcessDefinitionParser.class.getResourceAsStream("/process/ProcessDefinition.xsd")) {
+				log.trace("Compiling process definition schema.");
+				SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+				// schema is thread-safe
+				PD_SCHEMA_INSTANCE = factory.newSchema(new StreamSource(in));
+			} catch (Exception e) {
+				throw new RuntimeException("Unable to compile process definition schema.", e);
+			}
+		}
+	}
+
+	/**
+	 * Parses an XML representation of a process definition. The representation is being validated in order to suffice
+	 * the related XML schema.
+	 * 
+	 * @param processDefinitionInputStream
+	 *            The process definition.
+	 * @return A new process definition.
+	 * @throws ProcessDefinitionParserException
+	 *             Thrown in case of error parsing the process definition.
+	 */
+	public ProcessDefinition parse(InputStream processDefinitionInputStream) throws ProcessDefinitionParserException {
+		XMLEventReader reader = null;
+		final ProcessDefinition pd = new ProcessDefinition();
+		log.debug("Parsing and validating process definition.");
+		try {
+
+			// Standard implementation of XMLInputFactory seems not to be thread-safe
+			XMLInputFactory inputFactory = XMLInputFactory.newInstance();
+			reader = inputFactory.createXMLEventReader(processDefinitionInputStream);
+
+			final List<StartElement> transitionElements = new ArrayList<>();
+			final List<StartEvent> startEvents = new ArrayList<>();
+			
+			reader = new EventReaderDelegate(reader) {
+
+				@Override
+				public XMLEvent nextEvent() throws XMLStreamException {
+					XMLEvent event = super.nextEvent();
+
+					switch (event.getEventType()) {
+					case XMLStreamConstants.START_ELEMENT:
+						StartElement element = event.asStartElement();
+						QName qname = element.getName();
+						
+						if (NS.equals(qname.getNamespaceURI())) {
+							log.trace("Found process description element '{}'.", qname.getLocalPart());
+							Attribute id = element.getAttributeByName(new QName("id"));
+							
+							switch (qname.getLocalPart()) {
+							case "ProcessDefinition":
+								if (id != null) {
+									pd.setId(id.getValue());
+								}
+								break;
+							case "StartEvent":
+								StartEvent startEvent = new StartEvent();
+								if (id != null) {
+									startEvent.setId(id.getValue());
+								}
+								startEvents.add(startEvent);
+								break;
+							case "EndEvent":
+								EndEvent endEvent = new EndEvent();
+								if (id != null) {
+									endEvent.setId(id.getValue());
+									pd.getEndEvents().put(id.getValue(), endEvent);
+								}
+								break;
+							case "Transition":
+								transitionElements.add(element);
+								break;
+							case "Task":
+								TaskInfo taskInfo = new TaskInfo();
+								if (id != null) {
+									taskInfo.setId(id.getValue());
+									pd.getTaskInfos().put(id.getValue(), taskInfo);
+								}
+								Attribute async = element.getAttributeByName(new QName("async"));
+								if (async != null) {
+									taskInfo.setAsync(Boolean.valueOf(async.getValue()));
+								}
+								Attribute implementingClass = element.getAttributeByName(new QName("class"));
+								if (implementingClass != null) {
+									taskInfo.setTaskImplementingClass(implementingClass.getValue());
+								}
+								break;
+							}
+							
+						}
+						
+						break;
+					}
+
+					return event;
+				}
+
+			};
+
+			// validator is not thread-safe
+			Validator validator = LazyProcessDefinitionSchemaHolder.PD_SCHEMA_INSTANCE.newValidator();
+			validator.validate(new StAXSource(reader));
+			log.trace("Process definition successfully schema validated.");
+
+			// perform some basic checks
+			log.trace("Building model and performing some plausibility checks.");
+			if (startEvents.size() != 1) {
+				throw new ProcessDefinitionParserException("A ProcessDefinition must contain exactly one single StartEvent.");
+			}
+			pd.setStartEvent(startEvents.get(0));
+			
+			// link transitions
+			Iterator<StartElement> transitions = transitionElements.iterator();
+			while (transitions.hasNext()) {
+				StartElement element = transitions.next();
+				Transition transition = new Transition();
+				Attribute id = element.getAttributeByName(new QName("id"));
+				if (id != null) {
+					transition.setId(id.getValue());
+				}
+				Attribute conditionExpression = element.getAttributeByName(new QName("conditionExpression"));
+				if (conditionExpression != null) {
+					transition.setConditionExpression(conditionExpression.getValue());
+				}
+				Attribute from = element.getAttributeByName(new QName("from"));
+				if (from != null) {
+					ProcessNode fromNode = pd.getProcessNode(from.getValue());
+					if (fromNode == null) {
+						throw new ProcessDefinitionParserException("Transition's 'from'-attribute refers to a non-existing event or task '" + from.getValue() + '.');
+					}
+					if (fromNode instanceof EndEvent) {
+						throw new ProcessDefinitionParserException("Transition cannot start from end event.");
+					}
+					transition.setFrom(fromNode);
+					fromNode.getOutgoingTransitions().add(transition);
+				}
+				Attribute to = element.getAttributeByName(new QName("to"));
+				if (to != null) {
+					ProcessNode toNode = pd.getProcessNode(to.getValue());
+					if (toNode == null) {
+						throw new ProcessDefinitionParserException("Transition's 'to'-attribute refers to a non-existing event or task '" + to.getValue() + '.');
+					}
+					transition.setTo(toNode);
+					toNode.getIncomingTransitions().add(transition);
+				}
+				if (transition.getConditionExpression() == null && Objects.equals(transition.getFrom(), transition.getTo())) {
+					throw new ProcessDefinitionParserException("Transition's 'from' equals its 'to'. Since no 'conditionExpression' has been set this will cause a loop.");
+				}
+			}
+			log.debug("Process definition '{}' successfully parsed.", pd.getId());
+			return pd;
+
+		} catch (ProcessDefinitionParserException e) {
+			throw e;
+		} catch (XMLStreamException|IOException e) {
+			throw new ProcessDefinitionParserException("Unable to read process definition from inputstream.", e);
+		} catch (SAXException e) {
+			throw new ProcessDefinitionParserException("Schema validation of process description failed.", e);
+		} catch (Exception e) {
+			throw new ProcessDefinitionParserException("Internal error creating process definition from inputstream.", e);
+		} finally {
+			if (reader != null) {
+				try {
+					reader.close();
+				} catch (XMLStreamException e) {
+					// error freeing resources
+				}
+			}
+		}
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParserException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParserException.java
new file mode 100644
index 00000000..1ea811c6
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParserException.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process;
+
+/**
+ * Exception thrown in case of error parsing a process definition.
+ * 
+ * @author tknall
+ * 
+ */
+public class ProcessDefinitionParserException extends Exception {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Creates a new parser exception providing a {@code message} describing the reason and the {@code cause}.
+	 * 
+	 * @param message
+	 *            The message.
+	 * @param cause
+	 *            The cause.
+	 */
+	public ProcessDefinitionParserException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	/**
+	 * Creates a new parser exception providing a {@code message} describing the reason.
+	 * 
+	 * @param message
+	 *            The message.
+	 */
+	public ProcessDefinitionParserException(String message) {
+		super(message);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java
new file mode 100644
index 00000000..b5028542
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java
@@ -0,0 +1,424 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process;
+
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluationContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluator;
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessInstanceStoreDAO;
+import at.gv.egiz.eaaf.core.api.idp.process.Task;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.ProcessExecutionException;
+import at.gv.egiz.eaaf.core.impl.idp.process.dao.ProcessInstanceStore;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.EndEvent;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.ProcessDefinition;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.ProcessNode;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.StartEvent;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.TaskInfo;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.Transition;
+
+/**
+ * Process engine implementation allowing starting and continuing processes as well as providing means for cleanup actions.
+ */
+public class ProcessEngineImpl implements ProcessEngine {
+ 
+	private Logger log = LoggerFactory.getLogger(getClass());
+
+	@Autowired ProcessInstanceStoreDAO piStoreDao;
+	@Autowired ApplicationContext context;
+	
+	private ProcessDefinitionParser pdp = new ProcessDefinitionParser();
+
+	private Map<String, ProcessDefinition> processDefinitions = new ConcurrentHashMap<String, ProcessDefinition>();
+
+	private final static String MDC_CTX_PI_NAME = "processInstanceId";
+	private final static String MDC_CTX_TASK_NAME = "taskId";
+
+	private ExpressionEvaluator transitionConditionExpressionEvaluator;
+
+	@Override
+	public void registerProcessDefinition(ProcessDefinition processDefinition) {
+		log.info("Registering process definition '{}'.", processDefinition.getId());
+		processDefinitions.put(processDefinition.getId(), processDefinition);
+	}
+
+	@Override
+	public String registerProcessDefinition(InputStream processDefinitionInputStream) throws ProcessDefinitionParserException{
+		ProcessDefinition pd = pdp.parse(processDefinitionInputStream);
+		registerProcessDefinition(pd);
+		return pd.getId();
+	}
+
+	/**
+	 * Sets the process definitions.
+	 *
+	 * @param processDefinitions
+	 *            The process definitions.
+	 * @throws IllegalArgumentException
+	 *             In case the process definitions contain definitions with the same identifier.
+	 */
+	public void setProcessDefinitions(Iterable<ProcessDefinition> processDefinitions) {
+		this.processDefinitions.clear();
+		for (ProcessDefinition pd : processDefinitions) {
+			if (this.processDefinitions.containsKey(pd.getId())) {
+				throw new IllegalArgumentException("Duplicate process definition identifier '" + pd.getId() + "'.");
+			}
+			registerProcessDefinition(pd);
+		}
+	}
+
+	/**
+	 * Sets an expression evaluator that should be used to process transition condition expressions.
+	 * @param transitionConditionExpressionEvaluator The expression evaluator.
+	 */
+	public void setTransitionConditionExpressionEvaluator(
+			ExpressionEvaluator transitionConditionExpressionEvaluator) {
+		this.transitionConditionExpressionEvaluator = transitionConditionExpressionEvaluator;
+	}
+
+
+	@Override
+	public String createProcessInstance(String processDefinitionId, ExecutionContext executionContext) throws ProcessExecutionException {
+		// look for respective process definition
+		ProcessDefinition pd = processDefinitions.get(processDefinitionId);
+		if (pd == null) {
+			throw new ProcessExecutionException("Unable to find process definition for process '" + processDefinitionId + "'.");
+		}
+		// create and keep process instance
+		ProcessInstance pi = new ProcessInstance(pd, executionContext);
+		log.info("Creating process instance from process definition '{}': {}", processDefinitionId, pi.getId());
+
+		try {
+			saveOrUpdateProcessInstance(pi);
+			
+		} catch (EAAFException e) {
+			throw new ProcessExecutionException("Unable to persist process instance.", e);
+		}
+
+		return pi.getId();
+	}
+
+	@Override
+	public String createProcessInstance(String processDefinitionId) throws ProcessExecutionException {
+		return createProcessInstance(processDefinitionId, null);
+	}
+
+	@Override
+	public void start(IRequest pendingReq) throws ProcessExecutionException {
+		try {
+			if (StringUtils.isEmpty(pendingReq.getProcessInstanceId())) {
+				log.error("Pending-request with id:" + pendingReq.getPendingRequestId() 
+					+ " includes NO 'ProcessInstanceId'");
+				throw new ProcessExecutionException("Pending-request with id:" + pendingReq.getPendingRequestId() 
+					+ " includes NO 'ProcessInstanceId'");
+			}
+			
+			ProcessInstance pi = loadProcessInstance(pendingReq.getProcessInstanceId());
+
+			if (pi == null ) {
+				throw new ProcessExecutionException("Process instance '" + pendingReq.getProcessInstanceId() + "' does not exist.");
+				
+			}
+			
+			MDC.put(MDC_CTX_PI_NAME, pi.getId());
+
+			if (!ProcessInstanceState.NOT_STARTED.equals(pi.getState())) {
+				throw new ProcessExecutionException("Process instance '" + pi.getId() + "' has already been started (current state is " + pi.getState() + ").");
+			}
+			log.info("Starting process instance '{}'.", pi.getId());
+			// execute process
+			pi.setState(ProcessInstanceState.STARTED);
+			execute(pi, pendingReq);
+
+			//store ProcessInstance if it is not already ended
+			if (!ProcessInstanceState.ENDED.equals(pi.getState()))
+				saveOrUpdateProcessInstance(pi);
+				
+		} catch (EAAFException e) {
+			throw new ProcessExecutionException("Unable to load/save process instance.", e);
+
+		} finally {
+			MDC.remove(MDC_CTX_PI_NAME);
+		}
+	}
+	
+	@Override
+	public void signal(IRequest pendingReq) throws ProcessExecutionException {
+
+		try {
+			if (StringUtils.isEmpty(pendingReq.getProcessInstanceId())) {
+				log.error("Pending-request with id:" + pendingReq.getPendingRequestId() 
+					+ " includes NO 'ProcessInstanceId'");
+				throw new ProcessExecutionException("Pending-request with id:" + pendingReq.getPendingRequestId() 
+					+ " includes NO 'ProcessInstanceId'");
+			}
+			
+			ProcessInstance pi = loadProcessInstance(pendingReq.getProcessInstanceId());
+
+			if (pi == null ) {
+				throw new ProcessExecutionException("Process instance '" + pendingReq.getProcessInstanceId() + "' does not exist.");
+				
+			}
+			
+			MDC.put(MDC_CTX_PI_NAME, pi.getId());
+
+			if (!ProcessInstanceState.SUSPENDED.equals(pi.getState())) {
+				throw new ProcessExecutionException("Process instance '" + pi.getId() + "' has not been suspended (current state is " + pi.getState() + ").");
+			}
+
+			log.info("Waking up process instance '{}'.", pi.getId());
+			pi.setState(ProcessInstanceState.STARTED);
+
+			//put pending-request ID on execution-context because it could be changed
+			pi.getExecutionContext().put(EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID, pendingReq.getPendingRequestId());
+			
+			execute(pi, pendingReq);
+
+			//store ProcessInstance if it is not already ended
+			if (!ProcessInstanceState.ENDED.equals(pi.getState()))
+				saveOrUpdateProcessInstance(pi);
+						
+		} catch (EAAFException e) {
+			throw new ProcessExecutionException("Unable to load/save process instance.", e);
+
+		} finally {
+			MDC.remove(MDC_CTX_PI_NAME);
+		}
+	}
+	
+
+	/**
+	 * Instantiates a task implementation given by a {@link TaskInfo}.
+	 * @param ti The task info.
+	 * @return A Task implementation or {@code null} if the task info does not reference any task implementing classes.
+	 * @throws ProcessExecutionException Thrown in case of error (when the referenced class does not implement {@link Task} for instance).
+	 */
+	private Task createTaskInstance(TaskInfo ti) throws ProcessExecutionException {
+		String clazz = StringUtils.trimToNull(ti.getTaskImplementingClass());
+		Task task = null;
+		
+		if (clazz != null) {
+			log.debug("Instantiating task implementing class '{}'.", clazz);
+			Object instanceClass = null;
+			try {
+				instanceClass = context.getBean(clazz);
+				
+			} catch (Exception e) {
+				throw new ProcessExecutionException("Unable to get class '" + clazz + "' associated with task '" + ti.getId() + "' .", e);
+				
+			}
+			if (instanceClass == null || !(instanceClass instanceof Task)) {
+				throw new ProcessExecutionException("Class '" + clazz + "' associated with task '" + ti.getId() + "' is not assignable to " + Task.class.getName() + ".");
+				
+			}
+			try {
+				task = (Task) instanceClass;
+				
+			} catch (Exception e) {
+				throw new ProcessExecutionException("Unable to instantiate class '" + clazz + "' associated with task '" + ti.getId() + "' .", e);
+			}
+		}
+
+		return task;
+	}
+
+	/**
+	 * Starts/executes a given process instance.
+	 * @param pi The process instance.
+	 * @param pendingReq 
+	 * @throws ProcessExecutionException Thrown in case of error.
+	 */
+	private void execute(final ProcessInstance pi, IRequest pendingReq) throws ProcessExecutionException {
+		if (ProcessInstanceState.ENDED.equals(pi.getState())) {
+			throw new ProcessExecutionException("Process for instance '" + pi.getId() + "' has already been ended.");
+		}
+		ProcessDefinition pd = pi.getProcessDefinition();
+		ProcessNode processNode = pd.getProcessNode(pi.getNextId());
+		log.debug("Processing node '{}'.", processNode.getId());
+		
+		// distinguish process node types StartEvent, TaskInfo and EndEvent
+		
+		if (processNode instanceof TaskInfo) {
+			// TaskInfo types need to be executed
+			TaskInfo ti = (TaskInfo) processNode;
+			MDC.put(MDC_CTX_TASK_NAME, ti.getId());
+			try {
+				log.info("Processing task '{}'.", ti.getId());
+				Task task = createTaskInstance(ti);
+				if (task != null) {
+					try {
+						log.info("Executing task implementation for task '{}'.", ti.getId());
+						log.debug("Execution context before task execution: {}", pi.getExecutionContext().keySet());
+						pendingReq = task.execute(pendingReq, pi.getExecutionContext());
+						log.info("Returned from execution of task '{}'.", ti.getId());
+						log.debug("Execution context after task execution: {}", pi.getExecutionContext().keySet());
+					} catch (Throwable t) {
+						throw new ProcessExecutionException("Error executing task '" + ti.getId() + "'.", t);
+					}
+				} else {
+					log.debug("No task implementing class set.");
+				}
+			} finally {
+				MDC.remove(MDC_CTX_TASK_NAME);
+			}
+			
+		} else if (processNode instanceof EndEvent) {
+			log.info("Finishing process instance '{}'.", pi.getId());
+
+			try {
+				piStoreDao.remove(pi.getId());
+				
+			} catch (EAAFException e) {
+				throw new ProcessExecutionException("Unable to remove process instance.", e);
+				
+			}
+			pi.setState(ProcessInstanceState.ENDED);
+			log.debug("Final process context: {}", pi.getExecutionContext().keySet());
+			return;
+		}
+		
+		final ExpressionEvaluationContext expressionContext = new ExpressionEvaluationContextImpl(pi);
+		
+		// traverse pointer
+		Transition t = CollectionUtils.find(processNode.getOutgoingTransitions(), new Predicate<Transition>() {
+			@Override
+			public boolean evaluate(Transition transition) {
+				if (transitionConditionExpressionEvaluator != null && transition.getConditionExpression() != null) {
+					log.trace("Evaluating transition expression '{}'.", transition.getConditionExpression());
+					return transitionConditionExpressionEvaluator.evaluate(expressionContext, transition.getConditionExpression());
+				}
+				return true;
+			}
+		});
+		if (t == null) {
+			throw new ProcessExecutionException("No valid transition starting from process node '" + processNode.getId()+ "'.");
+		}
+		log.trace("Found suitable transition: {}", t);
+		// update pointer
+		log.trace("Shifting process token from '{}' to '{}'.", pi.getNextId(), t.getTo().getId());
+		pi.setNextId(t.getTo().getId());
+		
+		// inspect current task
+		if (t.getTo() instanceof TaskInfo && (((TaskInfo) t.getTo()).isAsync())) {
+			// immediately return in case of asynchonous task
+			log.info("Suspending process instance '{}' for asynchronous task '{}'.", pi.getId(), t.getTo().getId());
+			pi.setState(ProcessInstanceState.SUSPENDED);
+			return;
+		}
+		
+		// continue execution in case of StartEvent or Task
+		if (processNode instanceof StartEvent || processNode instanceof TaskInfo) {
+			execute(pi, pendingReq);
+		}
+	}
+
+	@Override
+	public ProcessInstance getProcessInstance(String processInstanceId) {
+
+		ProcessInstance processInstance;
+		try {
+			processInstance = loadProcessInstance(processInstanceId);
+
+		} catch (EAAFException e) {
+			throw new RuntimeException("The process instance '" + processInstanceId + "' could not be retrieved.", e);
+		}
+
+		if (processInstance == null) {
+			throw new IllegalArgumentException("The process instance '" + processInstanceId + "' does not/no longer exist.");
+		}
+
+		return processInstance;
+	}
+
+	/**
+	 * Persists a {@link ProcessInstance} to the database.
+	 * @param processInstance The object to persist.
+	 * @throws MOADatabaseException Thrown if an error occurs while accessing the database.
+	 */
+	private void saveOrUpdateProcessInstance(ProcessInstance processInstance) throws EAAFException {
+		ProcessInstanceStore store = new ProcessInstanceStore();
+
+		ExecutionContext ctx = processInstance.getExecutionContext();
+
+		Map<String, Serializable> ctxData = new HashMap<String, Serializable>();
+		for (String key : ctx.keySet()) {
+			ctxData.put(key, ctx.get(key));
+		}
+		store.setExecutionContextData(ctxData);
+
+		store.setNextTaskId(processInstance.getNextId());
+		store.setProcessDefinitionId(processInstance.getProcessDefinition().getId());
+
+		store.setProcessInstanceId(processInstance.getId());
+		store.setProcessState(processInstance.getState());
+
+		piStoreDao.saveOrUpdate(store);
+	}
+
+	/**
+	 * Load a {@link ProcessInstance} with a certain id from the database.
+	 * @param processInstanceId The process instance id
+	 * @return The process instance corresponding to the id or {@code null} if no such object is found.
+	 * @throws MOADatabaseException Thrown if an error occurs while accessing the database.
+	 */
+	private ProcessInstance loadProcessInstance(String processInstanceId) throws EAAFException {
+
+		ProcessInstanceStore piStore = piStoreDao.load(processInstanceId);
+
+		if (piStore == null) {
+			return null;
+		}
+
+		ExecutionContext executionContext = new ExecutionContextImpl(piStore.getProcessInstanceId());
+
+		Map<String, Serializable> executionContextData = piStore.getExecutionContextData();
+		for (String key : executionContextData.keySet()) {
+			executionContext.put(key, executionContextData.get(key));
+		}
+
+		ProcessInstance pi = new ProcessInstance(processDefinitions.get(piStore.getProcessDefinitionId()), executionContext);
+		pi.setNextId(piStore.getNextTaskId());
+		pi.setState(piStore.getProcessState());
+
+		return pi;
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.process.ProcessEngine#deleteProcessInstance(java.lang.String)
+	 */
+	@Override
+	public void deleteProcessInstance(String processInstanceId) throws ProcessExecutionException {
+		if (StringUtils.isEmpty(processInstanceId)) {
+			throw new ProcessExecutionException("Unable to remove process instance: ProcessInstanceId is empty");
+			
+		}
+			
+		try {
+			piStoreDao.remove(processInstanceId);
+			
+		} catch (EAAFException e) {
+			throw new ProcessExecutionException("Unable to remove process instance.", e);
+			
+		}
+		
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstance.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstance.java
new file mode 100644
index 00000000..ab6f7916
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstance.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.time.DurationFormatUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.ProcessDefinition;
+import at.gv.egiz.eaaf.core.impl.idp.process.support.SecureRandomHolder;
+
+/**
+ * Represents a process being executed. The process instance provides information about the process and its state.
+ * 
+ * @author tknall
+ * 
+ */
+public class ProcessInstance implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+	private static final int RND_ID_LENGTH = 22;
+
+	private ProcessDefinition processDefinition;
+	private String nextId;
+	private Date lru;
+	private ExecutionContext executionContext;
+	private ProcessInstanceState state = ProcessInstanceState.NOT_STARTED;
+
+	private Logger log = LoggerFactory.getLogger(getClass());
+
+	/**
+	 * Creates a new process instance, based on a given process definition and a
+	 * given execution context. If the given execution context is {@code null} a new execution context will be created.<p/>
+	 * The process instance id of the execution context will be newly generated if it is {@code null} in the execution context.
+	 * 
+	 * @param processDefinition
+	 *            The process definition.
+	 * @param executionContext
+	 *            The execution context (may be {@code null}). If {@code null} a new execution context will be created internally.
+	 */
+	ProcessInstance(ProcessDefinition processDefinition, ExecutionContext executionContext) {
+		this.processDefinition = processDefinition;
+		nextId = processDefinition.getStartEvent().getId();
+		if (executionContext == null) {
+			executionContext = new ExecutionContextImpl();
+		}
+		if (executionContext.getProcessInstanceId() == null) {
+			String pdIdLocalPart = RandomStringUtils.random(RND_ID_LENGTH, 0, 0, true, true, null,
+					SecureRandomHolder.getInstance());
+			executionContext.setProcessInstanceId(this.processDefinition.getId() + "-" + pdIdLocalPart);
+		} else {
+			log.debug("Using process instance id from execution context.");
+		}
+		log.debug("Creating process instance with id '{}'.", executionContext.getProcessInstanceId());
+		this.executionContext = executionContext;
+		touch();
+	}
+
+	/**
+	 * Returns the underlying process definition.
+	 * 
+	 * @return The underlying process definition.
+	 */
+	ProcessDefinition getProcessDefinition() {
+		touch();
+		return processDefinition;
+	}
+
+	/**
+	 * Returns the id of the process node to be executed next.
+	 * 
+	 * @return The process node pointer indicating the process node to be executed next.
+	 */
+	public String getNextId() {
+		touch();
+		return nextId;
+	}
+
+	/**
+	 * Sets the internal pointer to the process node to be executed next.
+	 * 
+	 * @param nextId
+	 *            The process node id to be executed next.
+	 */
+	void setNextId(String nextId) {
+		touch();
+		this.nextId = nextId;
+	}
+
+	/**
+	 * Returns the current state of the process instance.
+	 * 
+	 * @return The current state.
+	 */
+	public ProcessInstanceState getState() {
+		touch();
+		return state;
+	}
+
+	/**
+	 * Sets the current state of the process instance.
+	 * 
+	 * @param state
+	 *            The current state.
+	 */
+	void setState(ProcessInstanceState state) {
+		touch();
+		this.state = state;
+	}
+
+	public String getId() {
+		touch();
+		return executionContext.getProcessInstanceId();
+	}
+
+	/**
+	 * Updates the last recently used date of the process instance.
+	 */
+	private void touch() {
+		lru = new Date();
+	}
+
+	/**
+	 * Returns the date the process instance has been accessed last.
+	 * 
+	 * @return The last recently used date.
+	 */
+	Date getLru() {
+		return lru;
+	}
+
+	/**
+	 * Returns the associated execution context.
+	 * @return The execution context (never {@code null}).
+	 */
+	public ExecutionContext getExecutionContext() {
+		touch();
+		return executionContext;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("ProcessInstance [");
+		builder.append("id=").append(executionContext.getProcessInstanceId());
+		builder.append(", idle since=").append(
+				DurationFormatUtils.formatDurationWords(new Date().getTime() - this.lru.getTime(), true, true));
+		if (processDefinition != null) {
+			builder.append(", processDefinition.id=");
+			builder.append(processDefinition.getId());
+		}
+		if (nextId != null) {
+			builder.append(", nextId=");
+			builder.append(nextId);
+		}
+		builder.append(", executionContext=").append(executionContext);
+		builder.append("]");
+		return builder.toString();
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstanceState.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstanceState.java
new file mode 100644
index 00000000..cfb5479b
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstanceState.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process;
+
+/**
+ * Represents a certain process instance state.
+ * @author tknall
+ *
+ */
+public enum ProcessInstanceState {
+	
+	/**
+	 * Indicates that the process with this process instance has not yet been started.
+	 */
+	NOT_STARTED,
+	
+	/**
+	 * Indicates that the process is currently running.
+	 */
+	STARTED,
+	
+	/**
+	 * Indicates that the process has been suspended until being waken up by someonce calling {@code signal}.
+	 */
+	SUSPENDED,
+	
+	/**
+	 * Indicates that the process has been completed.
+	 */
+	ENDED
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStore.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStore.java
new file mode 100644
index 00000000..1ac65e10
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStore.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process.dao;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import at.gv.egiz.eaaf.core.impl.idp.process.ProcessInstanceState;
+
+public class ProcessInstanceStore implements Serializable{
+
+	private static final long serialVersionUID = -6147519767313903808L;
+
+	/**
+	 * A process instance identifier qualifies as natural primary key by satisfying these requirements
+	 * ("unique, constant, required"):
+	 * <ul>
+	 * <li>unique value</li>
+	 * <li>never changes (immutable)</li>
+	 * <li>never {@code null}</li>
+	 * </ul>
+	 */
+
+	private String processInstanceId;
+
+	private String processDefinitionId;
+
+	private String nextTaskId;
+
+	private ProcessInstanceState processState;
+	
+	private Map<String, Serializable> executionContextData; 
+	
+	public String getProcessInstanceId() {
+		return processInstanceId;
+	}
+
+	public String getProcessDefinitionId() {
+		return processDefinitionId;
+	}
+
+	public String getNextTaskId() {
+		return nextTaskId;
+	}
+
+	public ProcessInstanceState getProcessState() {
+		return processState;
+	}
+
+	@SuppressWarnings("unchecked")
+	public Map<String, Serializable> getExecutionContextData() {
+		return  executionContextData;
+	}
+
+	public void setProcessInstanceId(String processInstanceId) {
+		this.processInstanceId = processInstanceId;
+	}
+
+	public void setProcessDefinitionId(String processDefinitionId) {
+		this.processDefinitionId = processDefinitionId;
+	}
+
+	public void setNextTaskId(String nextTaskId) {
+		this.nextTaskId = nextTaskId;
+	}
+
+	public void setProcessState(ProcessInstanceState processState) {
+		this.processState = processState;
+	}
+
+	public void setExecutionContextData(Map<String, Serializable> executionContextData) {
+		this.executionContextData = executionContextData;
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDAOImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDAOImpl.java
new file mode 100644
index 00000000..be80a629
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDAOImpl.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process.dao;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessInstanceStoreDAO;
+import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+
+/**
+ * Database backed implementation of the {@link ProcessInstanceStoreDAO}
+ * interface.
+ */
+@Service("ProcessInstanceStoreage")
+public class ProcessInstanceStoreDAOImpl implements ProcessInstanceStoreDAO {
+
+	private Logger log = LoggerFactory.getLogger(getClass());
+
+	@Autowired ITransactionStorage transactionStorage;
+	
+	@Override
+	public void saveOrUpdate(ProcessInstanceStore pIStore) throws EAAFException {
+		try {
+			transactionStorage.put(pIStore.getProcessInstanceId(), pIStore, -1);
+			log.debug("Store process instance with='{}' in the database.", pIStore.getProcessInstanceId());
+			
+		} catch (EAAFException e) {
+			log.warn("ProcessInstanceStore could not be persisted to the database.");
+			throw e;
+		}
+	}
+
+	@Override
+	public ProcessInstanceStore load(String processInstanceId) throws EAAFException {
+		log.debug("Retrieve the ProcessInstanceStore for id='{}' from the database.", processInstanceId);
+		ProcessInstanceStore result = null;
+		try {
+			result = transactionStorage.get(processInstanceId, ProcessInstanceStore.class);
+
+		} catch (Exception e) {
+			log.error("There are multiple persisted processes with the same process instance id '{}'",
+				processInstanceId);
+
+			throw e;
+		}
+			
+		if (result != null) {
+			log.debug("Found process instance store for instance '{}'.", processInstanceId);
+			
+		} else {
+			log.debug("Unable to find process instance store for instance '{}'.", processInstanceId);
+			
+		}
+		
+		return result;
+	}
+
+	@Override
+	public void remove(String processInstanceId) throws EAAFException {
+
+		log.debug("Delete the ProcessInstanceStore for id='{}' from the database.", processInstanceId);		
+				
+		if (transactionStorage.containsKey(processInstanceId))
+			transactionStorage.remove(processInstanceId);
+		else 
+			log.trace("ProcessInstanceStore for id='{}' was not found and could therefore not be deleted.", processInstanceId);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/EndEvent.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/EndEvent.java
new file mode 100644
index 00000000..a8b757e3
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/EndEvent.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process.model;
+
+import java.io.Serializable;
+
+import org.apache.commons.collections4.CollectionUtils;
+
+/**
+ * Represents an end event. Process execution terminates when an end event is reached.
+ * 
+ * @author tknall
+ */
+public class EndEvent extends ProcessNode implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("EndEvent [");
+		if (getId() != null) {
+			builder.append("id=");
+			builder.append(getId());
+		}
+		if (CollectionUtils.isNotEmpty(getIncomingTransitions())) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("incomingTransitions=");
+			builder.append(getIncomingTransitions());
+		}
+		if (CollectionUtils.isNotEmpty(getOutgoingTransitions())) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("outgoingTransitions=");
+			builder.append(getOutgoingTransitions());
+		}
+		builder.append("]");
+		return builder.toString();
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessDefinition.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessDefinition.java
new file mode 100644
index 00000000..af4c0a1f
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessDefinition.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process.model;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import at.gv.egiz.eaaf.core.impl.idp.process.ProcessDefinitionParser;
+
+/**
+ * Represents a single process definition containing
+ * <ul>
+ * <li>a {@link StartEvent},</li>
+ * <li>one or more {@linkplain TaskInfo Tasks},</li>
+ * <li>one or more {@linkplain EndEvent EndEvents} and</li>
+ * <li>some {@linkplain Transition Transitions} linking StartEvents, Tasks and EndEvents.
+ * </ul>
+ * 
+ * @author tknall
+ * 
+ */
+public class ProcessDefinition {
+
+	private String id;
+	private StartEvent startEvent;
+	private Map<String, TaskInfo> taskInfos = new LinkedHashMap<>();
+	private Map<String, EndEvent> endEvents = new LinkedHashMap<>();
+
+	/**
+	 * Returns the unique identifier of the process definition.
+	 * 
+	 * @return The unique identifier (never {@code null} if process definition comes from
+	 *         {@link ProcessDefinitionParser}).
+	 */
+	public String getId() {
+		return id;
+	}
+
+	/**
+	 * Sets the unique identifier of the process definition.
+	 * 
+	 * @param id
+	 *            The unique identifier.
+	 */
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	/**
+	 * Returns the start event of the process definition.
+	 * 
+	 * @return The start event (never {@code null} if process definition comes from {@link ProcessDefinitionParser}).
+	 */
+	public StartEvent getStartEvent() {
+		return startEvent;
+	}
+
+	/**
+	 * Sets the start event of the process definition.
+	 * 
+	 * @param startEvent
+	 *            The start event.
+	 */
+	public void setStartEvent(StartEvent startEvent) {
+		this.startEvent = startEvent;
+	}
+
+	/**
+	 * Returns a map containing the tasks of the process definition.
+	 * 
+	 * @return The tasks (map is never {@code null} if process definition comes from {@link ProcessDefinitionParser}).
+	 */
+	public Map<String, TaskInfo> getTaskInfos() {
+		return taskInfos;
+	}
+
+	/**
+	 * Sets the map containing the tasks.
+	 * 
+	 * @param taskInfos
+	 *            The map containing the tasks.
+	 */
+	public void setTaskInfos(Map<String, TaskInfo> taskInfos) {
+		this.taskInfos = taskInfos;
+	}
+
+	/**
+	 * Returns a map containing the end events of the process description.
+	 * 
+	 * @return The map containing the end events (map is never {@code null} if process definition comes from
+	 *         {@link ProcessDefinitionParser}).
+	 */
+	public Map<String, EndEvent> getEndEvents() {
+		return endEvents;
+	}
+
+	/**
+	 * Sets a map containing the end events of the process description.
+	 * 
+	 * @param endEvents
+	 *            The map containing the end events.
+	 */
+	public void setEndEvents(Map<String, EndEvent> endEvents) {
+		this.endEvents = endEvents;
+	}
+
+	/**
+	 * Returns the process node associated with the given {@code id}.
+	 * 
+	 * @param id
+	 *            The identifier of the process node.
+	 * @return The process node (may be {code null} when no process node with the given {@code id} exists).
+	 */
+	public ProcessNode getProcessNode(String id) {
+		Objects.requireNonNull(id, "Identifier must not be null.");
+		if (startEvent != null && id.equals(startEvent.getId())) {
+			return startEvent;
+		}
+		TaskInfo task = taskInfos.get(id);
+		if (task != null) {
+			return task;
+		}
+		return endEvents.get(id);
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		if (id != null) {
+			builder.append("id=");
+			builder.append(id);
+		}
+		if (startEvent != null) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("startEvent=");
+			builder.append(startEvent);
+		}
+		if (taskInfos != null && !taskInfos.isEmpty()) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("tasksInfos=");
+			builder.append(taskInfos.values());
+		}
+		if (endEvents != null && !endEvents.isEmpty()) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("endEvents=");
+			builder.append(endEvents.values());
+		}
+		builder.insert(0, "ProcessDefinition [");
+		builder.append("]");
+		return builder.toString();
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessNode.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessNode.java
new file mode 100644
index 00000000..e1109336
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessNode.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import at.gv.egiz.eaaf.core.impl.idp.process.ProcessDefinitionParser;
+
+/**
+ * Represents a {@link StartEvent}, an {@link EndEvent} or a {@linkplain TaskInfo Task}.
+ * @author tknall
+ *
+ */
+public abstract class ProcessNode {
+
+	private String id;
+	private List<Transition> outgoingTransitions = new ArrayList<>();
+	private List<Transition> incomingTransitions = new ArrayList<>();
+
+	/**
+	 * Returns the unique identifier of the process node.
+	 * 
+	 * @return The unique identifier (never {@code null} if process node comes from a process definition from
+	 *         {@link ProcessDefinitionParser}).
+	 */
+	public String getId() {
+		return id;
+	}
+
+	/**
+	 * Sets the unique identifier of the process node.
+	 * @param id The unique identifier.
+	 */
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	/**
+	 * Returns a list of transitions pointing from this process node to another one.
+	 * @return A list of transitions (never {@code null} if process node comes from a process definition from {@link ProcessDefinitionParser}).
+	 */
+	public List<Transition> getOutgoingTransitions() {
+		return outgoingTransitions;
+	}
+
+	/**
+	 * Sets the list of transitions pointing from this process node to another one.
+	 * @param outgoingTransitions The list of transitions originating from this process node.
+	 */
+	public void setOutgoingTransitions(List<Transition> outgoingTransitions) {
+		this.outgoingTransitions = outgoingTransitions;
+	}
+
+	/**
+	 * Returns a list of transitions pointing from another process node to this one.
+	 * @return A list of transitions (never {@code null} if process node comes from a process definition from {@link ProcessDefinitionParser}).
+	 */
+	public List<Transition> getIncomingTransitions() {
+		return incomingTransitions;
+	}
+
+	/**
+	 * Sets the list of transitions pointing from another process node to this one.
+	 * @param incomingTransitions A list of transitions pointing to this process node.
+	 */
+	public void setIncomingTransitions(List<Transition> incomingTransitions) {
+		this.incomingTransitions = incomingTransitions;
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/StartEvent.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/StartEvent.java
new file mode 100644
index 00000000..3d3111c2
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/StartEvent.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process.model;
+
+import java.io.Serializable;
+
+import org.apache.commons.collections4.CollectionUtils;
+
+/**
+ * Represents a start event. Each process description contains a single start event. Process execution starts with a
+ * start event.
+ * 
+ * @author tknall
+ * 
+ */
+public class StartEvent extends ProcessNode implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("StartEvent [");
+		if (getId() != null) {
+			builder.append("id=");
+			builder.append(getId());
+		}
+		if (CollectionUtils.isNotEmpty(getIncomingTransitions())) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("incomingTransitions=");
+			builder.append(getIncomingTransitions());
+		}
+		if (CollectionUtils.isNotEmpty(getOutgoingTransitions())) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("outgoingTransitions=");
+
+			builder.append(getOutgoingTransitions());
+		}
+		builder.append("]");
+		return builder.toString();
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/TaskInfo.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/TaskInfo.java
new file mode 100644
index 00000000..b7171236
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/TaskInfo.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process.model;
+
+import java.io.Serializable;
+
+import org.apache.commons.collections4.CollectionUtils;
+
+import at.gv.egiz.eaaf.core.api.idp.process.Task;
+
+/**
+ * Represents information about a single task to be performed upon process execution.
+ * @author tknall
+ *
+ */
+public class TaskInfo extends ProcessNode implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+	private static final boolean DEFAULT_ASYNC = false;
+	
+	private String taskImplementingClass;
+	private boolean async = DEFAULT_ASYNC;
+	
+	/**
+	 * Determines if the task is marked asynchronous ({@code true}) or synchronous ({@code false}).
+	 * @return A flag indicating if the task should be executed asynchronously or synchronously. (Default: {@code false})
+	 */
+	public boolean isAsync() {
+		return async;
+	}
+
+	/**
+	 * Marks a task to executed asynchronously ({@code true}) or synchronously ({@code false}).
+	 * @param async The flag.
+	 */
+	public void setAsync(boolean async) {
+		this.async = async;
+	}
+
+	/**
+	 * Returns the class that implements the actual task (must implement {@link Task}).
+	 * @return The task implementing class.
+	 */
+	public String getTaskImplementingClass() {
+		return taskImplementingClass;
+	}
+
+	/**
+	 * Sets the class that implements the actual task (must implement {@link Task}).
+	 * @param taskImplementingClass The task implementing class.
+	 */
+	public void setTaskImplementingClass(String taskImplementingClass) {
+		this.taskImplementingClass = taskImplementingClass;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		if (getId() != null) {
+			builder.append("id=");
+			builder.append(getId());
+		}
+		if (async != DEFAULT_ASYNC) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("async=");
+			builder.append(async);
+		}
+		if (taskImplementingClass != null) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("taskImplementingClass=");
+			builder.append(taskImplementingClass);
+		}
+		if (CollectionUtils.isNotEmpty(getIncomingTransitions())) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("incomingTransitions=");
+			builder.append(getIncomingTransitions());
+		}
+		if (CollectionUtils.isNotEmpty(getOutgoingTransitions())) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("outgoingTransitions=");
+			builder.append(getOutgoingTransitions());
+		}
+		builder.insert(0, "TaskInfo [");
+		builder.append("]");
+		return builder.toString();
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/Transition.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/Transition.java
new file mode 100644
index 00000000..7ac26c20
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/Transition.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process.model;
+
+import java.io.Serializable;
+
+import at.gv.egiz.eaaf.core.impl.idp.process.ProcessDefinitionParser;
+
+/**
+ * Represents a single transition from a {@link StartEvent} or {@linkplain TaskInfo Task} to another
+ * {@linkplain TaskInfo Task} or {@link EndEvent}.
+ * 
+ * @author tknall
+ * 
+ */
+public class Transition implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	private String id;
+	private String conditionExpression;
+	private ProcessNode from;
+	private ProcessNode to;
+
+	/**
+	 * Returns the process node (effectively a {@link StartEvent} or {@linkplain TaskInfo Task}) the transition is
+	 * pointing from.
+	 * 
+	 * @return The transition's source process node (never {@code null} if transition comes from a process definition
+	 *         from {@link ProcessDefinitionParser}).
+	 */
+	public ProcessNode getFrom() {
+		return from;
+	}
+
+	/**
+	 * Sets the process node the transition is pointing from.
+	 * 
+	 * @param from
+	 *            The transition's source process node.
+	 */
+	public void setFrom(ProcessNode from) {
+		this.from = from;
+	}
+
+	/**
+	 * Returns the process node (effectively a {@linkplain TaskInfo Task} or {@link EndEvent}) the transition is
+	 * pointing to.
+	 * 
+	 * @return The transition's destination process node (never {@code null} if transition comes from a process
+	 *         definition from {@link ProcessDefinitionParser}).
+	 */
+	public ProcessNode getTo() {
+		return to;
+	}
+
+	/**
+	 * Sets the process node the transition is pointing to.
+	 * 
+	 * @param to
+	 *            The transition's destination process node.
+	 */
+	public void setTo(ProcessNode to) {
+		this.to = to;
+	}
+
+	/**
+	 * Returns the unique identifier of the transition.
+	 * 
+	 * @return The unique identifier (may be {@code null}).
+	 */
+	public String getId() {
+		return id;
+	}
+
+	/**
+	 * Sets the unique identifier of the transition.
+	 * 
+	 * @param id
+	 *            The unique identifier.
+	 */
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	/**
+	 * Returns the condition expression for this transition.
+	 * 
+	 * @return The condition expression (may be {@code null}).
+	 */
+	public String getConditionExpression() {
+		return conditionExpression;
+	}
+
+	/**
+	 * Sets the condition expression for this transition.
+	 * 
+	 * @param conditionExpression
+	 *            The condition expression.
+	 */
+	public void setConditionExpression(String conditionExpression) {
+		this.conditionExpression = conditionExpression;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		if (id != null) {
+			builder.append("id=");
+			builder.append(id);
+		}
+		if (from != null) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("from.id=");
+			builder.append(from.getId());
+		}
+		if (to != null) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("to.id=");
+			builder.append(to.getId());
+		}
+		if (conditionExpression != null) {
+			if (builder.length() > 0) {
+				builder.append(", ");
+			}
+			builder.append("conditionExpression=");
+			builder.append(conditionExpression);
+		}
+		builder.insert(0, "Transition [");
+		builder.append("]");
+		return builder.toString();
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/spring/SpringExpressionEvaluator.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/spring/SpringExpressionEvaluator.java
new file mode 100644
index 00000000..d301b77e
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/spring/SpringExpressionEvaluator.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process.spring;
+
+import java.util.Objects;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.commons.lang3.BooleanUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.expression.BeanFactoryResolver;
+import org.springframework.expression.Expression;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+
+import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluationContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluator;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.Transition;
+
+/**
+ * Expression evaluator for processing {@link Transition} conditions allowing to reference Spring beans from the
+ * application context.
+ * 
+ * @author tknall
+ * 
+ */
+public class SpringExpressionEvaluator implements ExpressionEvaluator {
+
+	private Logger log = LoggerFactory.getLogger(getClass());
+	private ExpressionParser parser = new SpelExpressionParser();
+	private StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
+
+	@Autowired(required = false)
+	private ApplicationContext ctx;
+
+	@PostConstruct
+	private void init() {
+		if (ctx != null) {
+			evaluationContext.setBeanResolver(new BeanFactoryResolver(ctx));
+		}
+	}
+
+	@Override
+	public boolean evaluate(ExpressionEvaluationContext expressionContext, String expression) {
+		Objects.requireNonNull(expression, "Expression must not be null.");
+		log.trace("Evaluating '{}'.", expression);
+
+		Expression expr = parser.parseExpression(expression);
+		Boolean result = expr.getValue(evaluationContext, expressionContext, Boolean.class);
+		if (result == null) {
+			log.warn("Evaluation of '{}' results in null-value.", expression);
+		} else {
+			log.debug("Expression '{}' -> {}", expression, result);
+		}
+
+		return BooleanUtils.isTrue(result);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractAuthSourceServlet.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractAuthSourceServlet.java
new file mode 100644
index 00000000..095c3439
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractAuthSourceServlet.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process.springweb;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
+import at.gv.egiz.eaaf.core.impl.idp.process.ProcessInstance;
+
+/**
+ * Abstract HttpServlet that provides means for retrieving the process engine (Spring Web required) as well as
+ * retrieving the underlying process instance and execution context evaluating a certain request parameter.
+ * 
+ * @author tknall
+ * 
+ */
+public abstract class AbstractAuthSourceServlet extends HttpServlet {
+
+	private static final long serialVersionUID = 1L;
+
+	private ProcessEngine processEngine;
+	
+	/**
+	 * Returns the name of the request parameter representing the respective instance id.
+	 * <p/>Default is {@code processInstanceId}.
+	 * @return The request parameter name.
+	 */
+	public String getProcessInstanceIdParameterName() {
+		return "processInstanceId";
+	}
+
+	/**
+	 * Returns the underlying process engine instance.
+	 * 
+	 * @return The process engine (never {@code null}).
+	 * @throws NoSuchBeanDefinitionException
+	 *             if no {@link ProcessEngine} bean was found.
+	 * @throws NoUniqueBeanDefinitionException
+	 *             if more than one {@link ProcessEngine} bean was found.
+	 * @throws BeansException
+	 *             if a problem getting the {@link ProcessEngine} bean occurred.
+	 * @throws IllegalStateException
+	 *             if the Spring WebApplicationContext was not found, which means that the servlet is used outside a
+	 *             Spring web environment.
+	 */
+	public synchronized ProcessEngine getProcessEngine() {
+		if (processEngine == null) {
+			WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
+			if (ctx == null) {
+				throw new IllegalStateException(
+						"Unable to find Spring WebApplicationContext. Servlet needs to be executed within a Spring web environment.");
+			}
+			processEngine = ctx.getBean(ProcessEngine.class);
+		}
+		return processEngine;
+	}
+
+	/**
+	 * Retrieves the process instance referenced by the request parameter {@link #getProcessInstanceIdParameterName()}.
+	 * 
+	 * @param request
+	 *            The HttpServletRequest.
+	 * @return The process instance (never {@code null}).
+	 * @throws NoSuchBeanDefinitionException
+	 *             if no {@link ProcessEngine} bean was found.
+	 * @throws NoUniqueBeanDefinitionException
+	 *             if more than one {@link ProcessEngine} bean was found.
+	 * @throws BeansException
+	 *             if a problem getting the {@link ProcessEngine} bean occurred.
+	 * @throws IllegalStateException
+	 *             if the Spring WebApplicationContext was not found, which means that the servlet is used outside a
+	 *             Spring web environment.
+	 * @throws IllegalArgumentException
+	 *             in case the process instance id referenced by the request parameter
+	 *             {@link #getProcessInstanceIdParameterName()} does not exist.
+	 */
+	public ProcessInstance getProcessInstance(HttpServletRequest request) {
+		String processInstanceId = StringUtils.trimToNull(request.getParameter(getProcessInstanceIdParameterName()));
+		if (processInstanceId == null) {
+			throw new IllegalArgumentException("Missing request parameter '" + getProcessInstanceIdParameterName() + "'.");
+		}
+		return getProcessEngine().getProcessInstance(processInstanceId);
+	}
+
+	/**
+	 * Retrieves the execution context for the respective process instance referenced by the request parameter
+	 * {@link #getProcessInstanceIdParameterName()}.
+	 * 
+	 * @param request
+	 *            The HttpServletRequest.
+	 * @return The execution context (never {@code null}).
+	 * @throws NoSuchBeanDefinitionException
+	 *             if no {@link ProcessEngine} bean was found.
+	 * @throws NoUniqueBeanDefinitionException
+	 *             if more than one {@link ProcessEngine} bean was found.
+	 * @throws BeansException
+	 *             if a problem getting the {@link ProcessEngine} bean occurred.
+	 * @throws IllegalStateException
+	 *             if the Spring WebApplicationContext was not found, which means that the servlet is used outside a
+	 *             Spring web environment.
+	 * @throws IllegalArgumentException
+	 *             in case the process instance id referenced by the request parameter
+	 *             {@link #getProcessInstanceIdParameterName()} does not exist.
+	 */
+	public ExecutionContext getExecutionContext(HttpServletRequest request) {
+		return getProcessInstance(request).getExecutionContext();
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractTask.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractTask.java
new file mode 100644
index 00000000..446bf690
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractTask.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process.springweb;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.filter.RequestContextFilter;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.process.Task;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+
+/**
+ * Abstract task implementation providing {@link HttpServletRequest} and {@link HttpServletResponse}.
+ * <p/>
+ * Note that this abstract task requires the Spring (web) framework including a {@link RequestContextFilter} to be set
+ * within {@code web.xml}.
+ * 
+ * <pre>
+ * ...
+ * &lt;filter&gt;
+ *   &lt;filter-name&gt;requestContextFilter&lt;/filter-name&gt;
+ *   &lt;filter-class&gt;org.springframework.web.filter.RequestContextFilter&lt;/filter-class&gt;
+ * &lt;/filter&gt;
+ * &lt;filter-mapping&gt;
+ *   &lt;filter-name&gt;requestContextFilter&lt;/filter-name&gt;
+ *   &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
+ * &lt;/filter-mapping&gt;
+ * ...
+ * </pre>
+ * 
+ * @author tknall
+ * @author tlenz
+ * 
+ */
+public abstract class AbstractTask implements Task {
+
+	/**
+	 * Executes the task providing the underlying {@link ExecutionContext} {@code executionContext} as well as the
+	 * respective {@link HttpServletRequest} and {@link HttpServletResponse}.
+	 * 
+	 * @param executionContext
+	 *            The execution context (never {@code null}).
+	 * @param request
+	 *            The HttpServletRequest (never {@code null}).
+	 * @param response
+	 *            The HttpServletResponse (never {@code null}).
+	 * @throws IllegalStateException
+	 *             Thrown in case the task is nur being run within the required environment. Refer to javadoc for
+	 *             further information.
+	 * @throws Exception
+	 *             Thrown in case of error executing the task.
+	 */
+	public abstract void execute(ExecutionContext executionContext, HttpServletRequest request,
+			HttpServletResponse response) throws TaskExecutionException;
+
+	/**
+	 * Executes the task providing the underlying {@link ExecutionContext} {@code executionContext} 
+	 * and the {@link IRequest} {@code pendingReq }as well as the
+	 * respective {@link HttpServletRequest} and {@link HttpServletResponse}.
+	 * 
+	 * This method sets the pending-request object of the task implementation and starts the 
+	 * {@code execute} method of the task
+	 * 
+	 * @param pendingReq The pending-request object (never {@code null}).
+	 * @param executionContext The execution context (never {@code null}).
+	 * @param request The HttpServletRequest (never {@code null}).
+	 * @param response The HttpServletResponse (never {@code null}).
+	 * @return The pending-request object, because Process-management works recursive
+	 * 
+	 * @throws IllegalStateException
+	 *             Thrown in case the task is being run within the required environment. Refer to javadoc for
+	 *             further information.
+	 * @throws Exception
+	 *             Thrown in case of error executing the task.
+	 */
+	protected abstract IRequest internalExecute(IRequest pendingReq, ExecutionContext executionContext, HttpServletRequest request,
+			HttpServletResponse response) throws TaskExecutionException;
+	
+	@Override
+	public IRequest execute(IRequest pendingReq, ExecutionContext executionContext) throws TaskExecutionException {
+		RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
+		if (requestAttributes != null && requestAttributes instanceof ServletRequestAttributes) {
+			HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
+			HttpServletResponse response = ((ServletRequestAttributes) requestAttributes).getResponse();
+			if (request == null || response == null) {
+				throw new IllegalStateException(
+						"Spring's RequestContextHolder did not provide HttpServletResponse. Did you forget to set the required org.springframework.web.filter.RequestContextFilter in your web.xml.");
+			}
+			return internalExecute(pendingReq, executionContext, request, response);
+		} else {
+			throw new IllegalStateException("Task needs to be executed within a Spring web environment.");
+		}
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/SpringWebExpressionEvaluator.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/SpringWebExpressionEvaluator.java
new file mode 100644
index 00000000..229735e3
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/SpringWebExpressionEvaluator.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process.springweb;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+
+import javax.annotation.PostConstruct;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.BooleanUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.expression.BeanFactoryResolver;
+import org.springframework.expression.Expression;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluationContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluator;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.Transition;
+
+/**
+ * Expression evaluator for processing {@link Transition} conditions allowing to
+ * <ul>
+ * <li>reference Spring beans from the application context using {@code @myBeanName...},</li>
+ * <li>{@link ExecutionContext} properties using {@code ctx['property']},</li>
+ * <li>Multi valued {@link HttpServletRequest} parameters using {@code requestParameters['foo']} (keep in mind that this
+ * expression returns an array of String values) and</li>
+ * <li>Single valued {@link HttpServletRequest} parameters using {@code requestParameter['foo']}</li>
+ * </ul>
+ * 
+ * @author tknall
+ * 
+ */
+public class SpringWebExpressionEvaluator implements ExpressionEvaluator {
+
+	private Logger log = LoggerFactory.getLogger(getClass());
+	private ExpressionParser parser = new SpelExpressionParser();
+	private StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
+
+	@Autowired(required = false)
+	private ApplicationContext ctx;
+
+	@Autowired(required = false)
+	private HttpServletRequest request;
+
+	@PostConstruct
+	private void init() {
+		if (ctx != null) {
+			evaluationContext.setBeanResolver(new BeanFactoryResolver(ctx));
+		}
+	}
+
+	/**
+	 * Evaluation context that provides access to {@link HttpServletRequest} parameters using
+	 * {@code requestParameter['foo']} for single value parameters or {@code requestParameters['foo']} for multi value
+	 * parameters. Basic calls to {@code ctx} will be delegated.
+	 * 
+	 * @author tknall
+	 * 
+	 */
+	private class SpringWebExpressionEvaluationContext implements ExpressionEvaluationContext {
+
+		private static final long serialVersionUID = 1L;
+
+		/**
+		 * Creates a new expression evaluation context, providing access to HttpServletRequest parameter(s).
+		 * 
+		 * @param delegate
+		 *            The original {@link ExpressionEvaluationContext} to be delegated to for {@code ctx['foo']}
+		 *            expressions.
+		 */
+		public SpringWebExpressionEvaluationContext(ExpressionEvaluationContext delegate) {
+			this.delegate = delegate;
+		}
+
+		private ExpressionEvaluationContext delegate;
+
+		@Override
+		public Map<String, Serializable> getCtx() {
+			return delegate.getCtx();
+		}
+
+		@SuppressWarnings("unused")
+		public Map<String, String> getRequestParameter() {
+			if (request != null) {
+				Map<String, String> singleValueMap = new HashMap<String, String>();
+				Iterator<Entry<String, String[]>> it = request.getParameterMap().entrySet().iterator();
+				while (it.hasNext()) {
+					Entry<String, String[]> entry = it.next();
+					if (ArrayUtils.isNotEmpty(entry.getValue())) {
+						singleValueMap.put(entry.getKey(), entry.getValue()[0]);
+					}
+				}
+				return singleValueMap;
+			} else {
+				return Collections.<String, String> emptyMap();
+			}
+		}
+
+		@SuppressWarnings("unused")
+		public Map<String, String[]> getRequestParameters() {
+			if (request != null) {
+				return request.getParameterMap();
+			} else {
+				return Collections.<String, String[]> emptyMap();
+			}
+		}
+
+	}
+
+	@Override
+	public boolean evaluate(ExpressionEvaluationContext expressionContext, String expression) {
+		Objects.requireNonNull(expression, "Expression must not be null.");
+		log.trace("Evaluating '{}'.", expression);
+
+		Expression expr = parser.parseExpression(expression);
+		Boolean result = null;
+		try {
+			result = expr.getValue(evaluationContext, new SpringWebExpressionEvaluationContext(expressionContext),
+					Boolean.class);
+			if (result == null) {
+				log.warn("Evaluation of '{}' results in null-value.", expression);
+			} else {
+				log.debug("Expression '{}' -> {}", expression, result);
+			}
+		} catch (Exception e) {
+			log.warn("Expression '{}' could not be processed.", expression, e);
+		}
+
+		return BooleanUtils.isTrue(result);
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java
new file mode 100644
index 00000000..0f581dae
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.process.support;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+/**
+ * Holder for a secure random instance following the initialization on demand holder design pattern. The secure random
+ * instance is a singleton that is initialized on first usage.
+ * 
+ * @author tknall
+ * 
+ */
+public class SecureRandomHolder {
+
+	private SecureRandomHolder() {
+	}
+
+	private static final SecureRandom SRND_INSTANCE;
+	static {
+		try {
+			SRND_INSTANCE = SecureRandom.getInstance("SHA1PRNG");
+		} catch (NoSuchAlgorithmException e) {
+			throw new RuntimeException("Unable to instantiate SHA1PRNG.", e);
+		}
+	}
+
+	/**
+	 * Returns a secure random generator instance.
+	 * @return The secure random instance.
+	 */
+	public static SecureRandom getInstance() {
+		return SecureRandomHolder.SRND_INSTANCE;
+	}
+
+}
\ No newline at end of file
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/logging/DummyRevisionsLogger.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/logging/DummyRevisionsLogger.java
new file mode 100644
index 00000000..5b6b8146
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/logging/DummyRevisionsLogger.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.logging;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
+
+public class DummyRevisionsLogger implements IRevisionLogger {
+	private static final Logger log = LoggerFactory.getLogger(DummyStatisticLogger.class);
+	
+	
+	@Override
+	public void logEvent(ISPConfiguration oaConfig, int eventCode, String message) {
+		log.trace("Dummy-logEventOperation");	
+
+	}
+
+	@Override
+	public void logEvent(int eventCode, String message) {
+		log.trace("Dummy-logEventOperation");
+
+	}
+
+	@Override
+	public void logEvent(String sessionID, String transactionID, int eventCode, String message) {
+		log.trace("Dummy-logEventOperation");
+
+	}
+
+	@Override
+	public void logEvent(String sessionID, String transactionID, int eventCode) {
+		log.trace("Dummy-logEventOperation");
+
+	}
+
+	@Override
+	public void logEvent(IRequest pendingRequest, int eventCode) {
+		log.trace("Dummy-logEventOperation");
+
+	}
+
+	@Override
+	public void logEvent(IRequest pendingRequest, int eventCode, String message) {
+		log.trace("Dummy-logEventOperation");
+
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/logging/DummyStatisticLogger.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/logging/DummyStatisticLogger.java
new file mode 100644
index 00000000..20f58b14
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/logging/DummyStatisticLogger.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.logging;
+
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.logging.IStatisticLogger;
+
+@Service("DummyStatisticLogger") 
+public class DummyStatisticLogger implements IStatisticLogger{
+	private static final Logger log = LoggerFactory.getLogger(DummyStatisticLogger.class);
+	
+	@Override
+	public void logSuccessOperation(IRequest protocolRequest,
+			IAuthData authData, boolean isSSOSession) {
+		log.trace("Dummy-logSuccessOperation");		
+	}
+
+	@Override
+	public void logErrorOperation(Throwable throwable) {
+		log.trace("Dummy-logErrorOperation");		
+	}
+
+	@Override
+	public void logErrorOperation(Throwable throwable, IRequest errorRequest) {
+		log.trace("Dummy-logErrorOperation");			
+	}
+
+	/* (non-Javadoc)
+	 * @see at.gv.egovernment.moa.id.advancedlogging.IStatisticLogger#testConnection()
+	 */
+	@Override
+	public void internalTesting() throws Exception {
+		log.trace("Dummy-logErrorOperation");
+		
+	}
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DOMUtils.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DOMUtils.java
new file mode 100644
index 00000000..f28700a1
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DOMUtils.java
@@ -0,0 +1,1243 @@
+/*******************************************************************************
+ *******************************************************************************/
+
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.parsers.SAXParser;
+import org.apache.xerces.parsers.XMLGrammarPreparser;
+import org.apache.xerces.util.SymbolTable;
+import org.apache.xerces.util.XMLGrammarPoolImpl;
+import org.apache.xerces.xni.grammars.XMLGrammarDescription;
+import org.apache.xerces.xni.grammars.XMLGrammarPool;
+import org.apache.xerces.xni.parser.XMLInputSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import at.gv.egiz.eaaf.core.api.data.XMLNamespaceConstants;
+
+/**
+ * Various utility functions for handling XML DOM trees.
+ * 
+ * The parsing methods in this class make use of some features internal to the
+ * Xerces DOM parser, mainly for performance reasons. As soon as JAXP
+ * (currently at version 1.2) is better at schema handling, it should be used as
+ * the parser interface.
+ * 
+ */
+public class DOMUtils {
+	private static final Logger log = LoggerFactory.getLogger(DOMUtils.class);
+	
+  /** Feature URI for namespace aware parsing. */
+  private static final String NAMESPACES_FEATURE =
+    "http://xml.org/sax/features/namespaces";
+  /** Feature URI for validating parsing. */
+  private static final String VALIDATION_FEATURE =
+    "http://xml.org/sax/features/validation";
+  /** Feature URI for schema validating parsing. */
+  private static final String SCHEMA_VALIDATION_FEATURE =
+    "http://apache.org/xml/features/validation/schema";
+  /** Feature URI for normalization of element/attribute values. */
+  private static final String NORMALIZED_VALUE_FEATURE =
+    "http://apache.org/xml/features/validation/schema/normalized-value";
+  /** Feature URI for parsing ignorable whitespace. */
+  private static final String INCLUDE_IGNORABLE_WHITESPACE_FEATURE =
+    "http://apache.org/xml/features/dom/include-ignorable-whitespace";
+  /** Feature URI for creating EntityReference nodes in the DOM tree. */
+  private static final String CREATE_ENTITY_REF_NODES_FEATURE =
+    "http://apache.org/xml/features/dom/create-entity-ref-nodes";
+  /** Property URI for providing external schema locations. */
+  private static final String EXTERNAL_SCHEMA_LOCATION_PROPERTY =
+    "http://apache.org/xml/properties/schema/external-schemaLocation";
+  /** Property URI for providing the external schema location for elements 
+   * without a namespace. */
+  private static final String EXTERNAL_NO_NAMESPACE_SCHEMA_LOCATION_PROPERTY =
+    "http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation";
+  
+  private static final String EXTERNAL_GENERAL_ENTITIES_FEATURE =
+  	"http://xml.org/sax/features/external-general-entities";
+  
+  private static final String EXTERNAL_PARAMETER_ENTITIES_FEATURE =
+	  "http://xml.org/sax/features/external-parameter-entities";
+  
+  public static final String DISALLOW_DOCTYPE_FEATURE =
+		  "http://apache.org/xml/features/disallow-doctype-decl";
+  
+  
+  
+  /** Property URI for the Xerces grammar pool. */
+  private static final String GRAMMAR_POOL =
+    org.apache.xerces.impl.Constants.XERCES_PROPERTY_PREFIX
+      + org.apache.xerces.impl.Constants.XMLGRAMMAR_POOL_PROPERTY;
+  /** A prime number for initializing the symbol table. */
+  private static final int BIG_PRIME = 2039;
+  /** Symbol table for the grammar pool. */
+  private static SymbolTable symbolTable = new SymbolTable(BIG_PRIME);
+  /** Xerces schema grammar pool. */
+  private static XMLGrammarPool grammarPool = new XMLGrammarPoolImpl();
+  /** Set holding the NamespaceURIs of the grammarPool, to prevent multiple
+    * entries of same grammars to the pool */
+  private static Set grammarNamespaces; 
+
+  static {
+    grammarPool.lockPool();
+    grammarNamespaces = new HashSet();
+  }
+
+  /**
+   * Preparse a schema and add it to the schema pool.
+   * The method only adds the schema to the pool if a schema having the same
+   * <code>systemId</code> (namespace URI) is not already present in the pool.
+   * 
+   * @param inputStream An <code>InputStream</code> providing the contents of
+   * the schema.
+   * @param systemId The systemId (namespace URI) to use for the schema.
+   * @throws IOException An error occurred reading the schema.
+   */
+  public static void addSchemaToPool(InputStream inputStream, String systemId)
+    throws IOException {
+    XMLGrammarPreparser preparser;
+
+    if (!grammarNamespaces.contains(systemId)) { 
+
+      grammarNamespaces.add(systemId);
+    
+      // unlock the pool so that we can add another grammar
+      grammarPool.unlockPool();
+	
+      // prepare the preparser
+      preparser = new XMLGrammarPreparser(symbolTable);
+      preparser.registerPreparser(XMLGrammarDescription.XML_SCHEMA, null);
+      preparser.setProperty(GRAMMAR_POOL, grammarPool);
+      preparser.setFeature(NAMESPACES_FEATURE, true);
+      preparser.setFeature(VALIDATION_FEATURE, true);
+	
+      // add the grammar to the pool
+      preparser.preparseGrammar(
+      XMLGrammarDescription.XML_SCHEMA,
+        new XMLInputSource(null, systemId, null, inputStream, null));
+	
+      // lock the pool again so that schemas are not added automatically
+      grammarPool.lockPool();
+    }
+  }
+
+  /**
+   * Parse an XML document from an <code>InputStream</code>.
+   * 
+   * @param inputStream The <code>InputStream</code> containing the XML
+   * document.
+   * @param validating If <code>true</code>, parse validating.
+   * @param externalSchemaLocations A <code>String</code> containing namespace
+   * URI to schema location pairs, the same way it is accepted by the <code>xsi:
+   * schemaLocation</code> attribute. 
+   * @param externalNoNamespaceSchemaLocation The schema location of the
+   * schema for elements without a namespace, the same way it is accepted by the
+   * <code>xsi:noNamespaceSchemaLocation</code> attribute.
+   * @param entityResolver An <code>EntityResolver</code> to resolve external
+   * entities (schemas and DTDs). If <code>null</code>, it will not be set.
+   * @param errorHandler An <code>ErrorHandler</code> to decide what to do
+   * with parsing errors. If <code>null</code>, it will not be set.
+   * @return The parsed XML document as a DOM tree.
+   * @throws SAXException An error occurred parsing the document.
+   * @throws IOException An error occurred reading the document.
+   * @throws ParserConfigurationException An error occurred configuring the XML
+   * parser.
+   */
+  public static Document parseDocument(
+    InputStream inputStream,
+    boolean validating,
+    String externalSchemaLocations,
+    String externalNoNamespaceSchemaLocation,
+    EntityResolver entityResolver,
+    ErrorHandler errorHandler,
+    Map<String, Object> parserFeatures)
+    throws  SAXException, IOException, ParserConfigurationException {
+
+    DOMParser parser;
+
+//    class MyEntityResolver implements EntityResolver {
+//
+//		public InputSource resolveEntity(String publicId, String systemId)
+//				throws SAXException, IOException {
+//		    return new InputSource(new ByteArrayInputStream(new byte[0]));
+//		}
+//    }
+
+
+		//if Debug is enabled make a copy of inputStream to enable debug output in case of SAXException
+		byte buffer [] = null;
+		ByteArrayInputStream baStream = null;
+		if(true == log.isDebugEnabled()) {
+			buffer = IOUtils.toByteArray(inputStream);
+			baStream = new ByteArrayInputStream(buffer);
+			
+		}	
+		
+		
+		
+    // create the DOM parser
+    if (symbolTable != null) {
+      parser = new DOMParser(symbolTable, grammarPool);
+    } else {
+      parser = new DOMParser();
+    }
+    
+    // set parser features and properties
+    try {
+	    parser.setFeature(NAMESPACES_FEATURE, true);
+	    parser.setFeature(VALIDATION_FEATURE, validating);
+	    parser.setFeature(SCHEMA_VALIDATION_FEATURE, validating);
+	    parser.setFeature(NORMALIZED_VALUE_FEATURE, false);
+	    parser.setFeature(INCLUDE_IGNORABLE_WHITESPACE_FEATURE, true);
+	    parser.setFeature(CREATE_ENTITY_REF_NODES_FEATURE, false);
+	    parser.setFeature(EXTERNAL_GENERAL_ENTITIES_FEATURE, false);
+	    parser.setFeature(EXTERNAL_PARAMETER_ENTITIES_FEATURE, false);
+	    
+	    //set external added parser features
+	    if (parserFeatures != null) {
+	    	for (Entry<String, Object> el : parserFeatures.entrySet()) {
+	    		String key = el.getKey();
+	    		if (StringUtils.isNotEmpty(key)) {
+	    			Object value = el.getValue();
+	    			if (value != null && value instanceof Boolean)	    		
+	    				parser.setFeature(key, (boolean)value);
+	    			
+	    			else
+	    				log.warn("This XML parser only allows features with 'boolean' values");
+	    			
+	    		} else 
+	    			log.warn("Can not set 'null' feature to XML parser");
+	    	}
+	    }
+	    
+	    //fix XXE problem
+	    //parser.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+	    
+	
+	    if (validating) {
+	      if (externalSchemaLocations != null) {
+	        parser.setProperty(
+	          EXTERNAL_SCHEMA_LOCATION_PROPERTY,
+	          externalSchemaLocations);
+	      }
+	      if (externalNoNamespaceSchemaLocation != null) {
+	        parser.setProperty(
+	          EXTERNAL_NO_NAMESPACE_SCHEMA_LOCATION_PROPERTY,
+	          externalNoNamespaceSchemaLocation);
+	      }
+	    }
+	
+	    // set entity resolver and error handler
+	    if (entityResolver != null) {
+	      parser.setEntityResolver(entityResolver);
+	    }
+	    if (errorHandler != null) {
+	      parser.setErrorHandler(errorHandler);
+	    }
+	
+	    // parse the document and return it
+	    // if debug is enabled: use copy of strem (baStream) else use orig stream
+	    if(null != baStream)
+	    	parser.parse(new InputSource(baStream));
+	    else 
+			parser.parse(new InputSource(inputStream));
+    } catch(SAXException e) {
+			if(true == log.isDebugEnabled() && null != buffer) {				
+				String xmlContent = new String(buffer);
+				log.debug("SAXException in:\n" + xmlContent);				 
+			} 
+		  throw(e);
+    }
+
+    return parser.getDocument();
+  }
+
+  /**
+   * Parse an XML document from an <code>InputStream</code>.
+   * 
+   * @param inputStream The <code>InputStream</code> containing the XML
+   * document.
+   * @param validating If <code>true</code>, parse validating.
+   * @param externalSchemaLocations A <code>String</code> containing namespace
+   * URI to schema location pairs, the same way it is accepted by the <code>xsi:
+   * schemaLocation</code> attribute. 
+   * @param externalNoNamespaceSchemaLocation The schema location of the
+   * schema for elements without a namespace, the same way it is accepted by the
+   * <code>xsi:noNamespaceSchemaLocation</code> attribute.
+   * @param entityResolver An <code>EntityResolver</code> to resolve external
+   * entities (schemas and DTDs). If <code>null</code>, it will not be set.
+   * @param errorHandler An <code>ErrorHandler</code> to decide what to do
+   * with parsing errors. If <code>null</code>, it will not be set.
+   * @return The parsed XML document as a DOM tree.
+   * @throws SAXException An error occurred parsing the document.
+   * @throws IOException An error occurred reading the document.
+   * @throws ParserConfigurationException An error occurred configuring the XML
+   * parser.
+   */
+  public static Document parseDocumentSimple(InputStream inputStream)
+    throws  SAXException, IOException, ParserConfigurationException {
+
+    DOMParser parser;
+			
+    parser = new DOMParser();
+    // set parser features and properties
+    parser.setFeature(NAMESPACES_FEATURE, true);
+    parser.setFeature(VALIDATION_FEATURE, false);
+    parser.setFeature(SCHEMA_VALIDATION_FEATURE, false);
+    parser.setFeature(NORMALIZED_VALUE_FEATURE, false);
+    parser.setFeature(INCLUDE_IGNORABLE_WHITESPACE_FEATURE, true);
+    parser.setFeature(CREATE_ENTITY_REF_NODES_FEATURE, false);
+		
+    parser.parse(new InputSource(inputStream));
+    
+    return parser.getDocument();
+  }
+
+  
+  /**
+   * Parse an XML document from an <code>InputStream</code>.
+   * 
+   * It uses a <code>MOAEntityResolver</code> as the <code>EntityResolver</code>
+   * and a <code>MOAErrorHandler</code> as the <code>ErrorHandler</code>.
+   * 
+   * @param inputStream The <code>InputStream</code> containing the XML
+   * document.
+   * @param validating If <code>true</code>, parse validating.
+   * @param externalSchemaLocations A <code>String</code> containing namespace
+   * URI to schema location pairs, the same way it is accepted by the <code>xsi:
+   * schemaLocation</code> attribute. 
+   * @param externalNoNamespaceSchemaLocation The schema location of the
+   * schema for elements without a namespace, the same way it is accepted by the
+   * <code>xsi:noNamespaceSchemaLocation</code> attribute.
+ * @param parserFeatures 
+   * @return The parsed XML document as a DOM tree.
+   * @throws SAXException An error occurred parsing the document.
+   * @throws IOException An error occurred reading the document.
+   * @throws ParserConfigurationException An error occurred configuring the XML
+   * parser.
+   */
+  public static Document parseDocument(
+    InputStream inputStream,
+    boolean validating,
+    String externalSchemaLocations,
+    String externalNoNamespaceSchemaLocation, Map<String, Object> parserFeatures)
+    throws SAXException, IOException, ParserConfigurationException {
+
+  
+	  
+    return parseDocument(
+      inputStream,
+      validating,
+      externalSchemaLocations,
+      externalNoNamespaceSchemaLocation,
+      new EAAFDomEntityResolver(),
+      null,
+      parserFeatures);
+  }
+
+  /**
+   * Parse an XML document from a <code>String</code>.
+   * 
+   * It uses a <code>MOAEntityResolver</code> as the <code>EntityResolver</code>
+   * and a <code>MOAErrorHandler</code> as the <code>ErrorHandler</code>.
+   * 
+   * @param xmlString The <code>String</code> containing the XML document.
+   * @param encoding The encoding of the XML document.
+   * @param validating If <code>true</code>, parse validating.
+   * @param externalSchemaLocations A <code>String</code> containing namespace
+   * URI to schema location pairs, the same way it is accepted by the <code>xsi:
+   * schemaLocation</code> attribute. 
+   * @param externalNoNamespaceSchemaLocation The schema location of the
+   * schema for elements without a namespace, the same way it is accepted by the
+   * <code>xsi:noNamespaceSchemaLocation</code> attribute.
+   * @return The parsed XML document as a DOM tree.
+   * @throws SAXException An error occurred parsing the document.
+   * @throws IOException An error occurred reading the document.
+   * @throws ParserConfigurationException An error occurred configuring the XML
+   * parser.
+   */
+  public static Document parseDocument(
+    String xmlString,
+    String encoding,
+    boolean validating,
+    String externalSchemaLocations,
+    String externalNoNamespaceSchemaLocation,
+    Map<String, Object> parserFeatures)
+    throws SAXException, IOException, ParserConfigurationException {
+
+    InputStream in = new ByteArrayInputStream(xmlString.getBytes(encoding));
+    return parseDocument(
+      in,
+      validating,
+      externalSchemaLocations,
+      externalNoNamespaceSchemaLocation,
+      parserFeatures);
+  }
+  
+  
+  /**
+   * Parse an XML document from a <code>String</code>.
+   * 
+   * It uses a <code>MOAEntityResolver</code> as the <code>EntityResolver</code>
+   * and a <code>MOAErrorHandler</code> as the <code>ErrorHandler</code>.
+   * 
+   * @param xmlString The <code>String</code> containing the XML document.
+   * @param encoding The encoding of the XML document.
+   * @param validating If <code>true</code>, parse validating.
+   * @param externalSchemaLocations A <code>String</code> containing namespace
+   * URI to schema location pairs, the same way it is accepted by the <code>xsi:
+   * schemaLocation</code> attribute. 
+   * @param externalNoNamespaceSchemaLocation The schema location of the
+   * schema for elements without a namespace, the same way it is accepted by the
+   * <code>xsi:noNamespaceSchemaLocation</code> attribute.
+   * @return The parsed XML document as a DOM tree.
+   * @throws SAXException An error occurred parsing the document.
+   * @throws IOException An error occurred reading the document.
+   * @throws ParserConfigurationException An error occurred configuring the XML
+   * parser.
+   */
+  public static Document parseDocument(
+    String xmlString,
+    String encoding,
+    boolean validating,
+    String externalSchemaLocations,
+    String externalNoNamespaceSchemaLocation)
+    throws SAXException, IOException, ParserConfigurationException {
+
+    InputStream in = new ByteArrayInputStream(xmlString.getBytes(encoding));
+    return parseDocument(
+      in,
+      validating,
+      externalSchemaLocations,
+      externalNoNamespaceSchemaLocation,
+      null);
+  }
+
+  /**
+   * Parse an UTF-8 encoded XML document from a <code>String</code>.
+   * 
+   * @param xmlString The <code>String</code> containing the XML document.
+   * @param validating If <code>true</code>, parse validating.
+   * @param externalSchemaLocations A <code>String</code> containing namespace
+   * URI to schema location pairs, the same way it is accepted by the <code>xsi:
+   * schemaLocation</code> attribute. 
+   * @param externalNoNamespaceSchemaLocation The schema location of the
+   * schema for elements without a namespace, the same way it is accepted by the
+   * <code>xsi:noNamespaceSchemaLocation</code> attribute.
+   * @return The parsed XML document as a DOM tree.
+   * @throws SAXException An error occurred parsing the document.
+   * @throws IOException An error occurred reading the document.
+   * @throws ParserConfigurationException An error occurred configuring the XML
+   * parser.
+   */
+  public static Document parseDocument(
+    String xmlString,
+    boolean validating,
+    String externalSchemaLocations,
+    String externalNoNamespaceSchemaLocation)
+    throws SAXException, IOException, ParserConfigurationException {
+
+    return parseDocument(
+      xmlString,
+      "UTF-8",
+      validating,
+      externalSchemaLocations,
+      externalNoNamespaceSchemaLocation);
+  }
+
+  /**
+   * A convenience method to parse an XML document validating.
+   * 
+   * @param inputStream The <code>InputStream</code> containing the XML
+   * document.
+   * @return The root element of the parsed XML document.
+   * @throws SAXException An error occurred parsing the document.
+   * @throws IOException An error occurred reading the document.
+   * @throws ParserConfigurationException An error occurred configuring the XML
+   * parser.
+   */
+  public static Element parseXmlValidating(InputStream inputStream)
+    throws ParserConfigurationException, SAXException, IOException {
+    return DOMUtils
+      .parseDocument(inputStream, true, XMLNamespaceConstants.ALL_SCHEMA_LOCATIONS, null, null)
+      .getDocumentElement();
+  }
+  
+  /**
+   * A convenience method to parse an XML document validating.
+   * 
+   * @param inputStream The <code>InputStream</code> containing the XML
+   * document.
+   * @param parserFeatures Set additional features to XML parser
+   * @return The root element of the parsed XML document.
+   * @throws SAXException An error occurred parsing the document.
+   * @throws IOException An error occurred reading the document.
+   * @throws ParserConfigurationException An error occurred configuring the XML
+   * parser.
+   */
+  public static Element parseXmlValidating(InputStream inputStream, Map<String, Object> parserFeatures)
+    throws ParserConfigurationException, SAXException, IOException {
+    return DOMUtils
+      .parseDocument(inputStream, true, XMLNamespaceConstants.ALL_SCHEMA_LOCATIONS, null, parserFeatures)
+      .getDocumentElement();
+  }
+  
+  /**
+   * A convenience method to parse an XML document non validating.
+   * This method disallow DocType declarations 
+   * 
+   * @param inputStream The <code>InputStream</code> containing the XML
+   * document.
+   * @return The root element of the parsed XML document.
+   * @throws SAXException An error occurred parsing the document.
+   * @throws IOException An error occurred reading the document.
+   * @throws ParserConfigurationException An error occurred configuring the XML
+   * parser.
+   */
+  public static Element parseXmlNonValidating(InputStream inputStream)
+    throws ParserConfigurationException, SAXException, IOException {	  
+    return DOMUtils
+      .parseDocument(inputStream, false, XMLNamespaceConstants.ALL_SCHEMA_LOCATIONS, null, 
+    		  Collections.unmodifiableMap(new HashMap<String, Object>() {
+    			  private static final long serialVersionUID = 1L;
+    			  {	
+    				  put(DOMUtils.DISALLOW_DOCTYPE_FEATURE, true);
+				
+    			  }
+    		  })).getDocumentElement();
+  }
+
+  /**
+   * Schema validate a given DOM element.
+   * 
+   * @param element The element to validate.
+   * @param externalSchemaLocations A <code>String</code> containing namespace
+   * URI to schema location pairs, the same way it is accepted by the <code>xsi:
+   * schemaLocation</code> attribute. 
+   * @param externalNoNamespaceSchemaLocation The schema location of the
+   * schema for elements without a namespace, the same way it is accepted by the
+   * <code>xsi:noNamespaceSchemaLocation</code> attribute.
+   * @return <code>true</code>, if the <code>element</code> validates against
+   * the schemas declared in it.
+   * @throws SAXException An error occurred parsing the document.
+   * @throws IOException An error occurred reading the document from its
+   * serialized representation.
+   * @throws ParserConfigurationException An error occurred configuring the XML
+   * @throws TransformerException An error occurred serializing the element.
+   */
+  public static boolean validateElement(
+    Element element,
+    String externalSchemaLocations,
+    String externalNoNamespaceSchemaLocation)
+    throws
+      ParserConfigurationException,
+      IOException,
+      SAXException,
+      TransformerException {
+
+    byte[] docBytes;
+    SAXParser parser;
+
+    // create the SAX parser
+    if (symbolTable != null) {
+      parser = new SAXParser(symbolTable, grammarPool);
+    } else {
+      parser = new SAXParser();
+    }
+
+    // serialize the document
+    docBytes = serializeNode(element, "UTF-8");
+
+    // set up parser features and attributes
+    parser.setFeature(NAMESPACES_FEATURE, true);
+    parser.setFeature(VALIDATION_FEATURE, true);
+    parser.setFeature(SCHEMA_VALIDATION_FEATURE, true);
+    parser.setFeature(EXTERNAL_GENERAL_ENTITIES_FEATURE, false);
+    parser.setFeature(DISALLOW_DOCTYPE_FEATURE, true);
+    
+    
+    if (externalSchemaLocations != null) {
+      parser.setProperty(
+        EXTERNAL_SCHEMA_LOCATION_PROPERTY,
+        externalSchemaLocations);
+    }
+    if (externalNoNamespaceSchemaLocation != null) {
+      parser.setProperty(
+        EXTERNAL_NO_NAMESPACE_SCHEMA_LOCATION_PROPERTY,
+        "externalNoNamespaceSchemaLocation");
+    }
+
+    // set up entity resolver and error handler
+    parser.setEntityResolver(new EAAFDomEntityResolver());
+
+    // parse validating
+    parser.parse(new InputSource(new ByteArrayInputStream(docBytes)));
+    return true;
+  }
+
+  
+  /**
+   * Schema validate a given DOM element.
+   * 
+   * @param element The element to validate.
+   * @param externalSchemaLocations A <code>String</code> containing namespace
+   * URI to schema location pairs, the same way it is accepted by the <code>xsi:
+   * schemaLocation</code> attribute. 
+   * @param externalNoNamespaceSchemaLocation The schema location of the
+   * schema for elements without a namespace, the same way it is accepted by the
+   * <code>xsi:noNamespaceSchemaLocation</code> attribute.
+   * @return <code>true</code>, if the <code>element</code> validates against
+   * the schemas declared in it.
+   * @throws SAXException An error occurred parsing the document.
+   * @throws IOException An error occurred reading the document from its
+   * serialized representation.
+   * @throws ParserConfigurationException An error occurred configuring the XML
+   * @throws TransformerException An error occurred serializing the element.
+   */
+  public static boolean validateElement(
+    Element element,
+    String externalSchemaLocations,
+    String externalNoNamespaceSchemaLocation,
+    EntityResolver entityResolver)
+    throws
+      ParserConfigurationException,
+      IOException,
+      SAXException,
+      TransformerException {
+
+    byte[] docBytes;
+    SAXParser parser;
+
+    // create the SAX parser
+    if (symbolTable != null) {
+      parser = new SAXParser(symbolTable, grammarPool);
+    } else {
+      parser = new SAXParser();
+    }
+
+    // serialize the document
+    docBytes = serializeNode(element, "UTF-8");
+
+    // set up parser features and attributes
+    parser.setFeature(NAMESPACES_FEATURE, true);
+    parser.setFeature(VALIDATION_FEATURE, true);
+    parser.setFeature(SCHEMA_VALIDATION_FEATURE, true);
+    
+    if (externalSchemaLocations != null) {
+      parser.setProperty(
+        EXTERNAL_SCHEMA_LOCATION_PROPERTY,
+        externalSchemaLocations);
+    }
+    if (externalNoNamespaceSchemaLocation != null) {
+      parser.setProperty(
+        EXTERNAL_NO_NAMESPACE_SCHEMA_LOCATION_PROPERTY,
+        "externalNoNamespaceSchemaLocation");
+    }
+
+    // set up entity resolver and error handler
+    parser.setEntityResolver(entityResolver);
+
+    // parse validating
+    parser.parse(new InputSource(new ByteArrayInputStream(docBytes)));
+    return true;
+  }
+  
+  /**
+   * Serialize the given DOM node.
+   * 
+   * The node will be serialized using the UTF-8 encoding.
+   * 
+   * @param node The node to serialize.
+   * @return String The <code>String</code> representation of the given DOM
+   * node.
+   * @throws TransformerException An error occurred transforming the
+   * node to a <code>String</code>.
+   * @throws IOException An IO error occurred writing the node to a byte array.
+   */
+  public static String serializeNode(Node node)
+    throws TransformerException, IOException {
+    return new String(serializeNode(node, "UTF-8", false), "UTF-8");
+  }
+
+
+  /**
+   * Serialize the given DOM node.
+   * 
+   * The node will be serialized using the UTF-8 encoding.
+   * 
+   * @param node The node to serialize.
+   * @param omitXmlDeclaration The boolean value for omitting the XML Declaration.
+   * @return String The <code>String</code> representation of the given DOM
+   * node.
+   * @throws TransformerException An error occurred transforming the
+   * node to a <code>String</code>.
+   * @throws IOException An IO error occurred writing the node to a byte array.
+   */
+  public static String serializeNode(Node node, boolean omitXmlDeclaration)
+    throws TransformerException, IOException {
+    return new String(serializeNode(node, "UTF-8", omitXmlDeclaration), "UTF-8");
+  }
+
+  /**
+   * Serialize the given DOM node.
+   * 
+   * The node will be serialized using the UTF-8 encoding.
+   * 
+   * @param node The node to serialize.
+   * @param omitXmlDeclaration The boolean value for omitting the XML Declaration.
+   * @param lineSeperator Sets the line seperator String of the parser
+   * @return String The <code>String</code> representation of the given DOM
+   * node.
+   * @throws TransformerException An error occurred transforming the
+   * node to a <code>String</code>.
+   * @throws IOException An IO error occurred writing the node to a byte array.
+   */
+  public static String serializeNode(Node node, boolean omitXmlDeclaration, String lineSeperator)
+    throws TransformerException, IOException {
+    return new String(serializeNode(node, "UTF-8", omitXmlDeclaration, lineSeperator), "UTF-8");
+  }
+  
+  /**
+   * Serialize the given DOM node to a byte array.
+   * 
+   * @param node The node to serialize.
+   * @param xmlEncoding The XML encoding to use.
+   * @return The serialized node, as a byte array. Using a compatible encoding
+   * this can easily be converted into a <code>String</code>.
+   * @throws TransformerException An error occurred transforming the node to a 
+   * byte array.
+   * @throws IOException An IO error occurred writing the node to a byte array.
+   */
+  public static byte[] serializeNode(Node node, String xmlEncoding)
+  throws TransformerException, IOException {
+    return serializeNode(node, xmlEncoding, false);
+  }
+  
+  /**
+   * Serialize the given DOM node to a byte array.
+   * 
+   * @param node The node to serialize.
+   * @param xmlEncoding The XML encoding to use.
+   * @param omitDeclaration The boolean value for omitting the XML Declaration.
+   * @return The serialized node, as a byte array. Using a compatible encoding
+   * this can easily be converted into a <code>String</code>.
+   * @throws TransformerException An error occurred transforming the node to a 
+   * byte array.
+   * @throws IOException An IO error occurred writing the node to a byte array.
+   */
+  public static byte[] serializeNode(Node node, String xmlEncoding, boolean omitDeclaration)
+    throws TransformerException, IOException {
+    return serializeNode(node, xmlEncoding, omitDeclaration, null);
+  }
+
+
+  /**
+   * Serialize the given DOM node to a byte array.
+   * 
+   * @param node The node to serialize.
+   * @param xmlEncoding The XML encoding to use.
+   * @param omitDeclaration The boolean value for omitting the XML Declaration.
+   * @param lineSeperator Sets the line seperator String of the parser
+   * @return The serialized node, as a byte array. Using a compatible encoding
+   * this can easily be converted into a <code>String</code>.
+   * @throws TransformerException An error occurred transforming the node to a 
+   * byte array.
+   * @throws IOException An IO error occurred writing the node to a byte array.
+   */
+  public static byte[] serializeNode(Node node, String xmlEncoding, boolean omitDeclaration, String lineSeperator)
+    throws TransformerException, IOException {
+
+    TransformerFactory transformerFactory = TransformerFactory.newInstance();
+    Transformer transformer = transformerFactory.newTransformer();
+    ByteArrayOutputStream bos = new ByteArrayOutputStream(16384);
+
+    transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+    transformer.setOutputProperty(OutputKeys.ENCODING, xmlEncoding);
+    String omit = omitDeclaration ? "yes" : "no";
+    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, omit);
+    if (null!=lineSeperator) {
+      transformer.setOutputProperty("{http://xml.apache.org/xalan}line-separator", lineSeperator);//does not work for xalan <= 2.5.1
+    }
+    transformer.transform(new DOMSource(node), new StreamResult(bos));
+
+    bos.flush();
+    bos.close();
+
+    return bos.toByteArray();
+  }
+
+  /**
+    * Return the text that a node contains. 
+    * 
+    * This routine:
+    * <ul>
+    * <li>Ignores comments and processing instructions.</li>
+    * <li>Concatenates TEXT nodes, CDATA nodes, and the results recursively
+    * processing EntityRef nodes.</li>
+    * <li>Ignores any element nodes in the sublist. (Other possible options are
+    * to recurse into element sublists or throw an exception.)</li>
+    * </ul>
+    * 
+    * @param node A DOM node from which to extract text.
+    * @return A String representing its contents.
+    */
+  public static String getText(Node node) {
+    if (!node.hasChildNodes()) {
+      return "";
+    }
+
+    StringBuffer result = new StringBuffer();
+    NodeList list = node.getChildNodes();
+
+    for (int i = 0; i < list.getLength(); i++) {
+      Node subnode = list.item(i);
+      if (subnode.getNodeType() == Node.TEXT_NODE) {
+        result.append(subnode.getNodeValue());
+      } else if (subnode.getNodeType() == Node.CDATA_SECTION_NODE) {
+        result.append(subnode.getNodeValue());
+      } else if (subnode.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
+        // Recurse into the subtree for text
+        // (and ignore comments)
+        result.append(getText(subnode));
+      }
+    }
+    return result.toString();
+  }
+
+  /**
+   * Build the namespace prefix to namespace URL mapping in effect for a given
+   * node.
+   * 
+   * @param node The context node for which build the map.
+   * @return The namespace prefix to namespace URL mapping (
+   * a <code>String</code> value to <code>String</code> value mapping).
+   */
+  public static Map getNamespaceDeclarations(Node node) {
+    Map nsDecls = new HashMap();
+    int i;
+
+    do {
+      if (node.hasAttributes()) {
+        NamedNodeMap attrs = node.getAttributes();
+
+        for (i = 0; i < attrs.getLength(); i++) {
+          Attr attr = (Attr) attrs.item(i);
+
+          // add prefix mapping if none exists
+          if ("xmlns".equals(attr.getPrefix())
+            || "xmlns".equals(attr.getName())) {
+
+            String nsPrefix =
+              attr.getPrefix() != null ? attr.getLocalName() : "";
+
+            if (nsDecls.get(nsPrefix) == null) {
+              nsDecls.put(nsPrefix, attr.getValue());
+            }
+          }
+        }
+      }
+    } while ((node = node.getParentNode()) != null);
+
+    return nsDecls;
+  }
+
+  /**
+   * Add all namespace declarations declared in the parent(s) of a given
+   * element and used in the subtree of the given element to the given element.  
+   * 
+   * @param context The element to which to add the namespaces.
+   */
+  public static void localizeNamespaceDeclarations(Element context) {
+    Node parent = context.getParentNode();
+
+    if (parent != null) {
+      Map namespaces = getNamespaceDeclarations(context.getParentNode());
+      Set nsUris = collectNamespaceURIs(context);
+      Iterator iter;
+
+      for (iter = namespaces.entrySet().iterator(); iter.hasNext();) {
+        Map.Entry e = (Map.Entry) iter.next();
+
+        if (nsUris.contains(e.getValue())) {
+          String prefix = (String) e.getKey();
+          String nsUri = (String) e.getValue();
+          String nsAttrName = "".equals(prefix) ? "xmlns" : "xmlns:" + prefix;
+
+          context.setAttributeNS(XMLNamespaceConstants.XMLNS_NS_URI, nsAttrName, nsUri);
+        }
+      }
+    }
+  }
+
+  /**
+   * Collect all the namespace URIs used in the subtree of a given element.
+   * 
+   * @param context The element that should be searched for namespace URIs.
+   * @return All namespace URIs used in the subtree of <code>context</code>,
+   * including the ones used in <code>context</code> itself.
+   */
+  public static Set collectNamespaceURIs(Element context) {
+    Set result = new HashSet();
+
+    collectNamespaceURIsImpl(context, result);
+    return result;
+  }
+
+  /**
+   * A recursive method to do the work of <code>collectNamespaceURIs</code>.
+   * 
+   * @param context The context element to evaluate.
+   * @param result The result, passed as a parameter to avoid unnecessary
+   * instantiations of <code>Set</code>.
+   */
+  private static void collectNamespaceURIsImpl(Element context, Set result) {
+    NamedNodeMap attrs = context.getAttributes();
+    NodeList childNodes = context.getChildNodes();
+    String nsUri;
+    int i;
+
+    // add the namespace of the context element
+    nsUri = context.getNamespaceURI();
+    if (nsUri != null && nsUri != XMLNamespaceConstants.XMLNS_NS_URI) {
+      result.add(nsUri);
+    }
+
+    // add all namespace URIs from attributes
+    for (i = 0; i < attrs.getLength(); i++) {
+      nsUri = attrs.item(i).getNamespaceURI();
+      if (nsUri != null && nsUri != XMLNamespaceConstants.XMLNS_NS_URI) {
+        result.add(nsUri);
+      }
+    }
+
+    // add all namespaces from subelements
+    for (i = 0; i < childNodes.getLength(); i++) {
+      Node node = childNodes.item(i);
+
+      if (node.getNodeType() == Node.ELEMENT_NODE) {
+        collectNamespaceURIsImpl((Element) node, result);
+      }
+    }
+  }
+
+  /**
+   * Check, that each attribute node in the given <code>NodeList</code> has its
+   * parent in the <code>NodeList</code> as well.
+   * 
+   * @param nodes The <code>NodeList</code> to check.
+   * @return <code>true</code>, if each attribute node in <code>nodes</code>
+   * has its parent in <code>nodes</code> as well.
+   */
+  public static boolean checkAttributeParentsInNodeList(NodeList nodes) {
+    Set nodeSet = new HashSet();
+    int i;
+
+    // put the nodes into the nodeSet
+    for (i = 0; i < nodes.getLength(); i++) {
+      nodeSet.add(nodes.item(i));
+    }
+
+    // check that each attribute node's parent is in the node list
+    for (i = 0; i < nodes.getLength(); i++) {
+      Node n = nodes.item(i);
+
+      if (n.getNodeType() == Node.ATTRIBUTE_NODE) {
+        Attr attr = (Attr) n;
+        Element owner = attr.getOwnerElement();
+
+        if (owner == null) {
+          if (!isNamespaceDeclaration(attr)) {
+            return false;
+          }
+        }
+
+        if (!nodeSet.contains(owner) && !isNamespaceDeclaration(attr)) {
+          return false;
+        }
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   * Convert an unstructured <code>NodeList</code> into a 
+   * <code>DocumentFragment</code>.
+   *
+   * @param nodeList Contains the node list to be converted into a DOM 
+   * DocumentFragment.
+   * @return the resulting DocumentFragment. The DocumentFragment will be 
+   * backed by a new DOM Document, i.e. all noded of the node list will be 
+   * cloned.
+   * @throws ParserConfigurationException An error occurred creating the
+   * DocumentFragment.
+   * @precondition The nodes in the node list appear in document order
+   * @precondition for each Attr node in the node list, the owning Element is 
+   * in the node list as well.
+   * @precondition each Element or Attr node in the node list is namespace 
+   * aware.
+   */
+  public static DocumentFragment nodeList2DocumentFragment(NodeList nodeList)
+    throws ParserConfigurationException {
+
+    DocumentBuilder builder =
+      DocumentBuilderFactory.newInstance().newDocumentBuilder();
+    Document doc = builder.newDocument();
+    DocumentFragment result = doc.createDocumentFragment();
+
+    if (null == nodeList || nodeList.getLength() == 0) {
+      return result;
+    }
+
+    int currPos = 0;
+    currPos =
+      nodeList2DocumentFragment(nodeList, currPos, result, null, null) + 1;
+
+    while (currPos < nodeList.getLength()) {
+      currPos =
+        nodeList2DocumentFragment(nodeList, currPos, result, null, null) + 1;
+    }
+    return result;
+  }
+
+  /**
+   * Helper method for the <code>nodeList2DocumentFragment</code>.
+   * 
+   * @param nodeList The <code>NodeList</code> to convert.
+   * @param currPos The current position in the <code>nodeList</code>.
+   * @param result The resulting <code>DocumentFragment</code>.
+   * @param currOrgElem The current original element.
+   * @param currClonedElem The current cloned element.
+   * @return The current position.
+   */
+  private static int nodeList2DocumentFragment(
+    NodeList nodeList,
+    int currPos,
+    DocumentFragment result,
+    Element currOrgElem,
+    Element currClonedElem) {
+
+    while (currPos < nodeList.getLength()) {
+      Node currentNode = nodeList.item(currPos);
+      switch (currentNode.getNodeType()) {
+        case Node.COMMENT_NODE :
+        case Node.PROCESSING_INSTRUCTION_NODE :
+        case Node.TEXT_NODE :
+          {
+            // Append current node either to resulting DocumentFragment or to 
+            // current cloned Element
+            if (null == currClonedElem) {
+              result.appendChild(
+                result.getOwnerDocument().importNode(currentNode, false));
+            } else {
+              // Stop processing if current Node is not a descendant of 
+              // current Element
+              if (!isAncestor(currOrgElem, currentNode)) {
+                return --currPos;
+              }
+
+              currClonedElem.appendChild(
+                result.getOwnerDocument().importNode(currentNode, false));
+            }
+            break;
+          }
+
+        case Node.ELEMENT_NODE :
+          {
+            Element nextCurrOrgElem = (Element) currentNode;
+            Element nextCurrClonedElem =
+              result.getOwnerDocument().createElementNS(
+                nextCurrOrgElem.getNamespaceURI(),
+                nextCurrOrgElem.getNodeName());
+
+            // Append current Node either to resulting DocumentFragment or to 
+            // current cloned Element
+            if (null == currClonedElem) {
+              result.appendChild(nextCurrClonedElem);
+              currOrgElem = nextCurrOrgElem;
+              currClonedElem = nextCurrClonedElem;
+            } else {
+              // Stop processing if current Node is not a descendant of
+              // current Element
+              if (!isAncestor(currOrgElem, currentNode)) {
+                return --currPos;
+              }
+
+              currClonedElem.appendChild(nextCurrClonedElem);
+            }
+
+            // Process current Node (of type Element) recursively
+            currPos =
+              nodeList2DocumentFragment(
+                nodeList,
+                ++currPos,
+                result,
+                nextCurrOrgElem,
+                nextCurrClonedElem);
+
+            break;
+          }
+
+        case Node.ATTRIBUTE_NODE :
+          {
+            Attr currAttr = (Attr) currentNode;
+
+            // GK 20030411: Hack to overcome problems with IAIK IXSIL
+            if (currAttr.getOwnerElement() == null)
+              break;
+            if (currClonedElem == null)
+              break;
+
+            // currClonedElem must be the owner Element of currAttr if 
+            // preconditions are met
+            currClonedElem.setAttributeNS(
+              currAttr.getNamespaceURI(),
+              currAttr.getNodeName(),
+              currAttr.getValue());
+            break;
+          }
+
+        default :
+          {
+            // All other nodes will be ignored
+          }
+      }
+
+      currPos++;
+    }
+
+    return currPos;
+  }
+
+  /**
+   * Check, if the given attribute is a namespace declaration.
+   * 
+   * @param attr The attribute to check.
+   * @return <code>true</code>, if the attribute is a namespace declaration,
+   * <code>false</code> otherwise.
+   */
+  private static boolean isNamespaceDeclaration(Attr attr) {
+    return XMLNamespaceConstants.XMLNS_NS_URI.equals(attr.getNamespaceURI());
+  }
+
+  /**
+   * Check, if a given DOM element is an ancestor of a given node.
+   * 
+   * @param candAnc The DOM element to check for being the ancestor.
+   * @param cand The node to check for being the child.
+   * @return <code>true</code>, if <code>candAnc</code> is an (indirect) 
+   * ancestor of <code>cand</code>; <code>false</code> otherwise.
+   */
+  public static boolean isAncestor(Element candAnc, Node cand) {
+    Node currPar = cand.getParentNode();
+
+    while (currPar != null) {
+      if (candAnc == currPar)
+        return true;
+      currPar = currPar.getParentNode();
+    }
+    return false;
+  }
+  
+  /**
+   * Selects the (first) element from a node list and returns it.
+   * 
+   * @param nl  The NodeList to get the element from.
+   * @return    The (first) element included in the node list or <code>null</code>
+   *            if the node list is <code>null</code> or empty or no element is
+   *            included in the list.
+   */
+  public static Element getElementFromNodeList (NodeList nl) {
+    if ((nl == null) || (nl.getLength() == 0)) {
+      return null;
+    }
+    for (int i=0; i<nl.getLength(); i++) {
+      Node node = nl.item(i);
+      if (node.getNodeType() == Node.ELEMENT_NODE)  {
+        return  (Element)node;
+      }
+    }
+    return null;
+  }
+  
+  /**
+   * Returns all child elements of the given element.
+   * 
+   * @param parent  The element to get the child elements from.
+   * 
+   * @return A list including all child elements of the given element.
+   *         Maybe empty if the parent element has no child elements.
+   */
+  public static List getChildElements (Element parent) {
+    Vector v = new Vector();
+    NodeList nl = parent.getChildNodes();
+    int length = nl.getLength();
+    for (int i=0; i < length; i++) {
+      Node node = nl.item(i);
+      if (node.getNodeType() == Node.ELEMENT_NODE) {
+        v.add((Element)node);
+      }
+    }
+    return v;
+  }
+  
+  /**
+   * Returns a byte array from given node.
+   * @param node
+   * @return
+   * @throws TransformerException
+   */
+  public static byte[] nodeToByteArray(Node node) throws TransformerException {
+	  Source source = new DOMSource(node);
+	  ByteArrayOutputStream out = new ByteArrayOutputStream();
+	  //StringWriter stringWriter = new StringWriter();
+	  Result result = new StreamResult(out);
+	  TransformerFactory factory = TransformerFactory.newInstance();
+	  Transformer transformer = factory.newTransformer();
+	  transformer.transform(source, result);
+	  return out.toByteArray();
+  }
+
+ 
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataURLBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataURLBuilder.java
new file mode 100644
index 00000000..de8fda45
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataURLBuilder.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+
+/**
+ * Builds a DataURL parameter meant for the security layer implementation
+ * to respond to.
+ * 
+ * @author Paul Ivancsics
+ * @version $Id$
+ */
+public class DataURLBuilder {
+	
+  /**
+   * Constructor for DataURLBuilder.
+   */
+  public DataURLBuilder() {
+    super();
+  }
+
+  /**
+   * Constructs a data URL for <code>VerifyIdentityLink</code> or <code>VerifyAuthenticationBlock</code>, 
+   * including the <code>MOASessionID</code> as a parameter.
+   * 
+   * @param authBaseURL base URL (context path) of the MOA ID Authentication component,
+   * 				 including a trailing <code>'/'</code>
+   * @param authServletName request part of the data URL
+   * @param pendingReqId sessionID to be included in the dataURL
+   * @return String
+   */
+  public String buildDataURL(String authBaseURL, String authServletName, String pendingReqId) {
+		String dataURL;		
+		if (!authBaseURL.endsWith("/"))
+			authBaseURL += "/";
+		
+		if (authServletName.startsWith("/"))
+			authServletName = authServletName.substring(1);
+		
+		dataURL = authBaseURL + authServletName;
+
+		if (StringUtils.isNotEmpty(pendingReqId))
+			dataURL = addParameter(dataURL, EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID, pendingReqId);
+		
+  	return dataURL;
+  }
+
+  /**
+   * Method addParameter.
+   * @param urlString represents the url 
+   * @param paramname is the parameter to be added
+   * @param value is the value of that parameter
+   * @return String
+   */
+  private String addParameter(String urlString, String paramname, String value) {
+    String url = urlString;
+    if (paramname != null) {
+      if (url.indexOf("?") < 0)
+        url += "?";
+      else
+        url += "&";
+      url += paramname + "=" + value;
+    }
+    return url;
+  }
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/EAAFDomEntityResolver.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/EAAFDomEntityResolver.java
new file mode 100644
index 00000000..5b39386c
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/EAAFDomEntityResolver.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ *******************************************************************************/
+
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import java.io.InputStream;
+
+import org.apache.xerces.util.URI;
+import org.apache.xerces.util.URI.MalformedURIException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+
+import at.gv.egiz.eaaf.core.api.data.XMLNamespaceConstants;
+
+/**
+ * An <code>EntityResolver</code> that looks up entities stored as
+ * local resources.
+ * 
+ * <p>The following DTDs are mapped to local resources: 
+ * <ul>
+ * <li>The XMLSchema.dtd</li>
+ * <li>The datatypes.dtd</li>
+ * </ul>
+ * </p>
+ * <p>For all other resources, an attempt is made to resolve them as resources,
+ * either absolute or relative to <code>Constants.SCHEMA_ROOT</code>.
+ * 
+ */
+public class EAAFDomEntityResolver implements EntityResolver {
+	private static final Logger log = LoggerFactory.getLogger(EAAFDomEntityResolver.class);
+	
+  /**
+   * Resolve an entity.
+   * 
+   * The <code>systemId</code> parameter is used to perform the lookup of the
+   * entity as a resource, either by interpreting the <code>systemId</code> as
+   * an absolute resource path, or by appending the last path component of
+   * <code>systemId</code> to <code>Constants.SCHEMA_ROOT</code>.
+   * 
+   * @param publicId The public ID of the resource.
+   * @param systemId The system ID of the resource.
+   * @return An <code>InputSource</code> from which the entity can be read, or
+   * <code>null</code>, if the entity could not be found.
+   * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String)
+   */
+  public InputSource resolveEntity(String publicId, String systemId) {
+    InputStream stream;
+    int slashPos;
+
+    if (publicId != null) {
+      // check if we can resolve some standard dtd's
+      if (publicId.equalsIgnoreCase("-//W3C//DTD XMLSchema 200102//EN")) {
+        return new InputSource(
+          getClass().getResourceAsStream(
+            XMLNamespaceConstants.SCHEMA_ROOT + "XMLSchema.dtd"));
+      } else if (publicId.equalsIgnoreCase("datatypes")) {
+        return new InputSource(
+          getClass().getResourceAsStream(
+        	XMLNamespaceConstants.SCHEMA_ROOT + "datatypes.dtd"));
+      }
+    } else if (systemId != null) {
+      // get the URI path
+      try {
+        URI uri = new URI(systemId);
+        systemId = uri.getPath();
+       
+        if (!"file".equals(uri.getScheme()) || "".equals(systemId.trim())) {
+          return null;
+        }
+        
+      } catch (MalformedURIException e) {
+        return null;
+      }
+      
+      // try to get the resource from the full path
+      stream = getClass().getResourceAsStream(systemId);
+      if (stream != null) {
+        InputSource source = new InputSource(stream);
+
+        source.setSystemId(systemId);
+        return source;
+      }
+
+      // try to get the resource from the last path component
+      slashPos = systemId.lastIndexOf('/');
+      if (slashPos >= 0 && systemId.length() > slashPos) {
+        systemId = systemId.substring(slashPos + 1, systemId.length());
+        stream =
+          getClass().getResourceAsStream(XMLNamespaceConstants.SCHEMA_ROOT + systemId);
+        if (stream != null) {
+          InputSource source = new InputSource(stream);
+
+          source.setSystemId(systemId);
+          return source;
+        }
+      }
+    }
+
+    return null; // nothing found - let the parser handle the entity
+  }
+}
\ No newline at end of file
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java
new file mode 100644
index 00000000..01fb7375
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ *******************************************************************************/
+
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+
+/**
+ * Utility for accessing files on the file system, and for reading from input streams.
+ * @author Paul Ivancsics
+ * @version $Id$
+ */
+public class FileUtils {
+  
+  /**
+   * Reads a file, given by URL, into a byte array.
+   * @param urlString file URL
+   * @return file content
+   * @throws IOException on any exception thrown
+   */
+  public static byte[] readURL(String urlString) throws IOException {	  
+    URL url = new URL(urlString);
+    InputStream in = new BufferedInputStream(url.openStream());
+    byte[] content = StreamUtils.readStream(in);
+    in.close();
+    return content;
+  }
+
+  /**
+   * Reads a file from a resource.
+   * @param name resource name
+   * @return file content as a byte array
+   * @throws IOException on any exception thrown
+   */
+  public static byte[] readResource(String name) throws IOException {
+    ClassLoader cl = FileUtils.class.getClassLoader();
+    BufferedInputStream in = new BufferedInputStream(cl.getResourceAsStream(name));
+    byte[] content = StreamUtils.readStream(in);
+    in.close();
+    return content;
+  }
+  /**
+   * Reads a file from a resource.
+   * @param name filename
+   * @param encoding character encoding
+   * @return file content
+   * @throws IOException on any exception thrown
+   */
+  public static String readResource(String name, String encoding) throws IOException {
+    byte[] content = readResource(name);
+    return new String(content, encoding);
+  }
+  
+  
+	/**
+	 * Returns the absolute URL of a given url which is relative to the parameter root
+	 * @param url
+	 * @param root
+	 * @return String
+	 * @throws MalformedURLException 
+	 */
+	public static String makeAbsoluteURL(String url, URI root) throws MalformedURLException {
+		return makeAbsoluteURL(url, root.toURL().toString());
+
+	}  
+  
+	/**
+	 * Returns the absolute URL of a given url which is relative to the parameter root
+	 * @param url
+	 * @param root
+	 * @return String
+	 */
+	public static String makeAbsoluteURL(String url, String root) {
+		//if url is relative to rootConfigFileDirName make it absolute 					
+		
+		File keyFile;
+		String newURL = url;
+
+		if(null == url) return  null;
+    
+		if (url.startsWith("http:/") || url.startsWith("https:/") || url.startsWith("file:/") || url.startsWith("ftp:/")) {
+			return url;
+			
+		} else {
+			// check if absolute - if not make it absolute
+			keyFile = new File(url);
+			if (!keyFile.isAbsolute()) {
+				keyFile = new File(root, url);
+
+				if (keyFile.toString().startsWith("file:"))
+					newURL = keyFile.toString();
+        
+				else
+					newURL = keyFile.toURI().toString();
+        
+			}
+			return newURL;
+		}
+	}  
+	
+	
+	 private static void copy( InputStream fis, OutputStream fos )
+	  {
+	    try
+	    {
+	      byte[] buffer = new byte[ 0xFFFF ];
+	      for ( int len; (len = fis.read(buffer)) != -1; )
+	        fos.write( buffer, 0, len );
+	    }
+	    catch( IOException e ) {
+	      System.err.println( e );
+	    }
+	    finally {
+	      if ( fis != null )
+	        try { fis.close(); } catch ( IOException e ) { e.printStackTrace(); }
+	      if ( fos != null )
+	        try { fos.close(); } catch ( IOException e ) { e.printStackTrace(); }
+	    }
+	  }
+	 
+	 public static void copyFile(File src, File dest)
+	  {
+	    try
+	    {
+	      copy( new FileInputStream( src ), new FileOutputStream( dest ) );
+	    }
+	    catch( IOException e ) {
+	      e.printStackTrace();
+	    }
+	  }
+  
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HTTPUtils.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HTTPUtils.java
new file mode 100644
index 00000000..cf1abaa7
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HTTPUtils.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+
+
+/**
+ * 
+ * @author Rudolf Schamberger
+ *
+ */
+public class HTTPUtils {
+
+//  /**
+//   * Utility used to obtainin correct encoded HTTP content.
+//   * Reads a given Content adressed by HTTP-URL into String. 
+//   * Content encoding is considered by using the Content-Type HTTP header charset value.
+//   * @param URL HTTP URL to read from.
+//   * @return String representation of content
+//   * @throws IOException on data-reading problems
+//   */
+//  public static String readHttpURL(String URL) 
+//    throws IOException {
+//      
+//    URL url = new URL(URL);
+//    HttpURLConnection conn = (HttpURLConnection)url.openConnection();
+//    conn.setRequestMethod("GET");
+//    String contentType = conn.getContentType();
+//    RE regExp = null;
+//    try {
+//        regExp = new RE("(;.*charset=)(\"*)(.*[^\"])");
+//    } catch (RESyntaxException e) {
+//        //RESyntaxException is not possible = expr. is costant
+//    }
+//    boolean charsetSupplied = regExp.match(contentType);
+//    String encoding = "ISO-8859-1"; 		//default HTTP encoding 
+//    if (charsetSupplied) {
+//      encoding = regExp.getParen(3);
+//    }
+//    InputStream instream = new BufferedInputStream(conn.getInputStream());
+//    InputStreamReader isr = new InputStreamReader(instream, encoding);
+//    Reader in = new BufferedReader(isr);
+//    int ch;
+//  	StringBuffer buffer = new StringBuffer();
+//    while ((ch = in.read()) > -1) {
+//  		buffer.append((char)ch);
+//  	}     
+//    in.close();
+//    conn.disconnect();
+//    return buffer.toString();
+//  }
+  
+  	/**
+  	 * Helper method to retrieve server URL including context path
+  	 * @param request HttpServletRequest
+  	 * @return Server URL including context path (e.g. http://localhost:8443/moa-id-auth
+  	 */
+  	public static String getBaseURL(HttpServletRequest request) {
+		StringBuffer buffer = new StringBuffer(getServerURL(request));
+		
+	    // add context path if available
+	    String contextPath = request.getContextPath();
+	    if (!StringUtils.isEmpty(contextPath)) {
+	    	buffer.append(contextPath);
+	    }
+		
+		return buffer.toString(); 
+	}
+	
+  	/**
+  	 * Helper method to retrieve server URL
+  	 * @param request HttpServletRequest
+  	 * @return Server URL (e.g. http://localhost:8443)
+  	 */
+	public static String getServerURL(HttpServletRequest request) {
+		StringBuffer buffer = new StringBuffer();
+		
+		// get protocol
+		String protocol = request.getScheme();
+		buffer.append(protocol).append("://");
+		
+		// server name
+		buffer.append(request.getServerName());
+		
+		// add port if necessary
+		int port = request.getServerPort();
+	    if ((protocol.equals("http") && port != 80) || (protocol.equals("https") && port != 443)) {
+	    	buffer.append(':');
+	    	buffer.append(port);
+	    }
+	
+	    return buffer.toString(); 
+	}
+	
+	/**
+	 * Extract the IDP PublicURLPrefix from authrequest
+	 * 
+	 * @param req HttpServletRequest
+	 * @return PublicURLPrefix <String> which ends always without /
+	 */
+	public static String extractAuthURLFromRequest(HttpServletRequest req) {
+	    String authURL = req.getScheme() + "://" + req.getServerName();
+	    if ((req.getScheme().equalsIgnoreCase("https") && req.getServerPort()!=443) || (req.getScheme().equalsIgnoreCase("http") && req.getServerPort()!=80)) { 
+	      authURL = authURL.concat(":" + req.getServerPort());
+	    }
+	    authURL = authURL.concat(req.getContextPath());
+	    return authURL;
+		
+	}
+	
+	/**
+	 * Extract the IDP requested URL from authrequest
+	 * 
+	 * @param req HttpServletRequest
+	 * @return RequestURL <String> which ends always without /
+	 */ 
+	public static String extractAuthServletPathFromRequest(HttpServletRequest req) {
+	    return extractAuthURLFromRequest(req).concat(req.getServletPath());
+	 	
+	}
+	
+	public static String addURLParameter(String url, String paramname,
+			String paramvalue) {
+		String param = paramname + "=" + paramvalue;
+		if (url.indexOf("?") < 0)
+			return url + "?" + param;
+		else
+			return url + "&" + param;
+	}
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java
new file mode 100644
index 00000000..3583a294
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ *******************************************************************************/
+
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+
+/**
+ * Utility for creating and loading key stores.
+ * 
+ * @author Paul Ivancsics
+ * @version $Id$
+ */
+public class KeyStoreUtils {
+	
+	/**
+	 * JAVA KeyStore
+	 */
+	private static final String KEYSTORE_TYPE_JKS = "JKS";
+	
+	/**
+	 * PKCS12 KeyStore
+	 */
+	private static final String KEYSTORE_TYPE_PKCS12 = "PKCS12";
+	
+	
+
+  /**
+   * Loads a key store from file.
+   * 
+   * @param keystoreType key store type
+   * @param urlString URL of key store
+   * @param password password protecting the key store
+   * @return key store loaded
+   * @throws IOException thrown while reading the key store from file
+   * @throws GeneralSecurityException thrown while creating the key store
+   */
+  public static KeyStore loadKeyStore(
+    String keystoreType,
+    String urlString,
+    String password)
+    throws IOException, GeneralSecurityException {
+
+    URL keystoreURL = new URL(urlString);
+    InputStream in = keystoreURL.openStream();
+    return loadKeyStore(keystoreType, in, password);
+  }
+  /**
+   * Loads a key store from an <code>InputStream</code>, and
+   * closes the <code>InputStream</code>.
+   * 
+   * @param keystoreType key store type
+   * @param in input stream
+   * @param password password protecting the key store
+   * @return key store loaded
+   * @throws IOException thrown while reading the key store from the stream
+   * @throws GeneralSecurityException thrown while creating the key store
+   */
+  public static KeyStore loadKeyStore(
+    String keystoreType,
+    InputStream in,
+    String password)
+    throws IOException, GeneralSecurityException {
+
+    char[] chPassword = null;
+    if (password != null)
+      chPassword = password.toCharArray();
+    KeyStore ks = KeyStore.getInstance(keystoreType);
+    ks.load(in, chPassword);
+    in.close();
+    return ks;
+  }
+  /**
+   * Creates a key store from X509 certificate files, aliasing them with
+   * the index in the <code>String[]</code>, starting with <code>"0"</code>.
+   * 
+   * @param keyStoreType key store type
+   * @param certFilenames certificate filenames
+   * @return key store created
+   * @throws IOException thrown while reading the certificates from file
+   * @throws GeneralSecurityException thrown while creating the key store
+   */
+  public static KeyStore createKeyStore(
+    String keyStoreType,
+    String[] certFilenames)
+    throws IOException, GeneralSecurityException {
+
+    KeyStore ks = KeyStore.getInstance(keyStoreType);
+    ks.load(null, null);
+    for (int i = 0; i < certFilenames.length; i++) {
+      Certificate cert = loadCertificate(certFilenames[i]);
+      ks.setCertificateEntry("" + i, cert);
+    }
+    return ks;
+  }
+
+  /**
+   * Loads an X509 certificate from file.
+   * @param certFilename filename
+   * @return the certificate loaded
+   * @throws IOException thrown while reading the certificate from file
+   * @throws GeneralSecurityException thrown while creating the certificate
+   */
+  private static Certificate loadCertificate(String certFilename)
+    throws IOException, GeneralSecurityException {
+
+    FileInputStream in = new FileInputStream(certFilename);
+    CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+    Certificate cert = certFactory.generateCertificate(in);
+    in.close();
+    return cert;
+  }
+  
+ 
+	/**
+	 * Loads a keyStore without knowing the keyStore type
+	 * @param keyStorePath URL to the keyStore
+	 * @param password Password protecting the keyStore
+	 * @return keyStore loaded
+	 * @throws KeyStoreException thrown if keyStore cannot be loaded
+	 * @throws FileNotFoundException 
+	 * @throws IOException 
+	 */
+  public static KeyStore loadKeyStore(String keyStorePath, String password) throws KeyStoreException, IOException{
+		
+		//InputStream is = new FileInputStream(keyStorePath);
+	  	URL keystoreURL = new URL(keyStorePath);
+	    InputStream in = keystoreURL.openStream();
+		InputStream isBuffered = new BufferedInputStream(in);				
+		return loadKeyStore(isBuffered, password);
+		
+	}
+	
+	/**
+	 * Loads a keyStore without knowing the keyStore type
+	 * @param in input stream
+	 * @param password Password protecting the keyStore
+	 * @return keyStore loaded
+	 * @throws KeyStoreException thrown if keyStore cannot be loaded
+	 * @throws FileNotFoundException 
+	 * @throws IOException 
+	 */
+public static KeyStore loadKeyStore(InputStream is, String password) throws KeyStoreException, IOException{		
+		is.mark(1024*1024);
+		KeyStore ks = null;
+		try {
+			try {				
+				ks = loadKeyStore(KEYSTORE_TYPE_PKCS12, is, password);
+			} catch (IOException e2) {
+				is.reset();				
+				ks = loadKeyStore(KEYSTORE_TYPE_JKS, is, password);
+			}
+		} catch(Exception e) {			
+			e.printStackTrace();
+
+		}
+		return ks;	
+						
+	}
+  
+	
+
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java
new file mode 100644
index 00000000..49b957cc
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java
@@ -0,0 +1,319 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * @author tlenz
+ *
+ */
+public class KeyValueUtils {
+	
+	public static final String KEY_DELIMITER = ".";
+	public static final String CSV_DELIMITER = ",";
+	
+	/**
+	 * Convert Java properties into a Map<String, String>
+	 * <br><br>
+	 * <b>Important:</b> The key/values from properties must be of type String! 
+	 * 
+	 * @param properties
+	 * @return
+	 */
+	public static Map<String, String> convertPropertiesToMap(Properties properties) {
+		return new HashMap<String, String>((Map) properties);
+				
+		//INFO Java8 solution ;)
+//				return properties.entrySet().stream().collect(
+//			    Collectors.toMap(
+//			            e -> e.getKey().toString(),
+//			            e -> e.getValue().toString()
+//			       )
+//			   );
+		
+	}
+	
+	/**
+	 * Extract the first child of an input key after a the prefix
+	 * 
+	 * @param key Full input key 
+	 * @param prefix Prefix 
+	 * @return Child key {String} if it exists or null
+	 */
+	public static String getFirstChildAfterPrefix(String key, String prefix) {		
+		String idAfterPrefix = removePrefixFromKey(key, prefix);
+		if (idAfterPrefix != null) {
+			int index = idAfterPrefix.indexOf(KEY_DELIMITER);
+			if (index > 0) {
+				String adding = idAfterPrefix.substring(0, index);
+				if (!(adding.isEmpty())) {
+					return adding;
+					
+				}
+			} else if (!(idAfterPrefix.isEmpty())) {
+				return idAfterPrefix;
+				
+			}
+			
+		}					
+		return null;
+	}
+	
+	/**
+	 * Extract the prefix from an input key
+	 * 
+	 * @param key Full input key
+	 * @param suffix Suffix of this key
+	 * @return Prefix {String} of the key or null if input key does not ends with postfix string 
+	 */
+	public static String getPrefixFromKey(String key, String suffix) {
+		if (key != null && key.endsWith(suffix)) {
+			String idPreforeSuffix = key.substring(0, key.length()-suffix.length());			
+			if (idPreforeSuffix.endsWith(KEY_DELIMITER))
+				return idPreforeSuffix.substring(0, idPreforeSuffix.length()-1);
+			else
+				return idPreforeSuffix;
+		}
+		return null;
+		
+	}
+	
+	/**
+	 * Remove a prefix string from a key
+	 * 
+	 * @param key Full input key
+	 * @param prefix Prefix, which should be removed
+	 * @return The suffix of the input key or null if the input does not starts with the prefix
+	 */
+	public static String removePrefixFromKey(String key, String prefix) {
+		if (prefix == null)
+			prefix = new String();
+		
+		if (key!=null && key.startsWith(prefix)) {
+			String afterPrefix = key.substring(prefix.length()); 
+			int index = afterPrefix.indexOf(KEY_DELIMITER);
+
+			if (index == 0) {
+				afterPrefix = afterPrefix.substring(1);
+				
+			}
+			return afterPrefix;
+			
+		}		
+		return null;
+	}
+	
+	/**
+	 * Remove a prefix string from all keys in {Map<String, String>} of key/value pairs
+	 * 
+	 * @param keys Input data of key/value pairs
+	 * @param prefix Prefix which should be removed
+	 * @return {Map<String, String>} of key/value pairs without prefix in key, but never null
+	 */
+	public static Map<String, String> removePrefixFromKeys(Map<String, String> keys, String prefix) {
+		Map<String, String> result = new HashMap<String, String>();
+		Iterator<Entry<String, String>> interator = keys.entrySet().iterator();
+		while(interator.hasNext()) {
+			Entry<String, String> el = interator.next();
+			String newKey = removePrefixFromKey(el.getKey(), prefix);			
+			if (StringUtils.isNotEmpty(newKey)) {
+				result.put(newKey, el.getValue());
+			}			
+		}
+		
+		return result;
+	}
+
+	/**
+	 * Get a subset of key/value pairs which starts with a prefix string
+	 * The Prefix is removed from the key
+	 * 
+	 * @param keys Input data of key/value pairs
+	 * @param prefix Prefix string
+	 * @return {Map<String, String>} of key/value pairs without prefix in key, but never null
+	 */
+	public static Map<String, String> getSubSetWithPrefix(Map<String, String> keys, String prefix) {
+		return removePrefixFromKeys(keys, prefix);
+	}
+	
+	
+	/**
+	 * Add a prefix to key/value pairs to make the key absolute according to key namespace convention
+	 * 
+	 * @param input Input key/value pairs which should be updated
+	 * @param prefix Key prefix, which should be added if the key is not absolute
+	 * @param absolutIdentifier Key identifier, which indicates an absolute key
+	 * @return {Map<String, String>} of key/value pairs in which all keys are absolute but never null
+	 */
+	public static Map<String, String> makeKeysAbsolut(Map<String, String> input, String prefix, String absolutIdentifier) {
+		Map<String, String> result = new HashMap<String, String>();
+		Iterator<Entry<String, String>> interator = input.entrySet().iterator();
+		while(interator.hasNext()) {
+			Entry<String, String> el = interator.next();
+			if (!el.getKey().startsWith(absolutIdentifier)) {
+				//key is not absolute -> add prefix
+				result.put(prefix 
+						+ KEY_DELIMITER
+						+ el.getKey(), 
+						el.getValue());
+								
+			} else {
+				//key is absolute
+				result.put(el.getKey(), el.getValue());
+			}
+		}
+		return result;
+	}
+	
+	/**
+	 * Get the parent key string from an input key
+	 * 
+	 * @param key input key
+	 * @return parent key or the empty String if no parent exists
+	 */
+	public static String getParentKey(String key) {
+		if (StringUtils.isNotEmpty(key)) {
+			int index = key.lastIndexOf(KEY_DELIMITER);
+			if (index > 0) {
+				return key.substring(0, index);
+				
+			}			
+		}
+		
+		return new String();
+	}
+
+	/**
+	 * Find the highest free list counter
+	 * 
+	 * @param input Array of list keys
+	 * @param listPrefix {String} prefix of the list
+	 * @return {int} highest free list counter
+	 */
+	public static int findNextFreeListCounter(String[] input,
+			String listPrefix) {
+		List<Integer> counters = new ArrayList<Integer>();
+		if (input == null || input.length == 0)
+			return 0;
+		
+		else {
+			for (String key : input) {
+				String listIndex = getFirstChildAfterPrefix(key, listPrefix);
+				counters.add(Integer.parseInt(listIndex));
+			
+			}		
+			Collections.sort(counters);		
+			return counters.get(counters.size()-1) + 1;
+		}
+	}
+
+	/**
+	 * Find the highest free list counter
+	 * 
+	 * @param keySet {Set<String>} of list keys
+	 * @param listPrefix {String} prefix of the list
+	 * @return {int} highest free list counter
+	 */
+	public static int findNextFreeListCounter(Set<String> keySet,
+			String listPrefix) {
+		if (keySet.isEmpty())
+			return 0;
+		
+		String[] array = new String[keySet.size()];
+		keySet.toArray(array);
+		return findNextFreeListCounter(array, listPrefix);
+	}
+	
+	
+	/**
+	 * Normalize a CSV encoded list of value of an key/value pair
+	 * 
+	 * This method removes all whitespace at the begin or the 
+	 * end of CSV values and remove newLine signs at the end of value.
+	 * The ',' is used as list delimiter
+	 * 
+	 * @param value CSV encoded input data
+	 * @return normalized CSV encoded data or null if {value} is null or empty
+	 */
+	public static String normalizeCSVValueString(String value) {
+		String normalizedCodes = null;
+		if (StringUtils.isNotEmpty(value)) {			
+			String[] codes = value.split(CSV_DELIMITER);
+			for (String el: codes) {
+				if (normalizedCodes == null)
+					normalizedCodes = StringUtils.chomp(el.trim());
+				else
+					normalizedCodes += "," + StringUtils.chomp(el.trim());
+				
+			}
+		}
+		return normalizedCodes;
+	}
+	
+	
+	/**
+	 * Check a String if it is a comma separated list of values
+	 * 
+	 * This method uses the ',' as list delimiter.
+	 * 
+	 * @param value CSV encoded input data
+	 * @return true if the input data contains a ',' and has more then 1 list element, otherwise false
+	 */
+	public static boolean isCSVValueString(String value) {
+		if (StringUtils.isNotEmpty(value)) {			
+			String[] codes = value.split(CSV_DELIMITER);
+			if (codes.length >= 2) {
+				if (StringUtils.isNotEmpty(codes[1].trim()))
+					return true;
+				
+			}			
+		}
+		
+		return false;
+	}
+	
+	/**
+	 * Convert a CSV list to a List of CSV values
+	 * <br><br>
+	 * This method removes all whitespace at the begin or the 
+	 * end of CSV values and remove newLine signs at the end of value.
+	 * The ',' is used as list delimiter
+	 * 
+	 * @param csv CSV encoded input data
+	 * @return List of CSV normalized values, but never null
+	 */
+	public static List<String> getListOfCSVValues(String csv) {
+		List<String> list = new ArrayList<String>();
+		if (StringUtils.isNotEmpty(csv)) {		
+			String[] values = csv.split(CSV_DELIMITER);
+			for (String el: values)
+				list.add(el.trim());
+		
+		}
+		
+		return list;
+	}
+	
+	/**
+	 * This method remove all newline delimiter (\n or \r\n) from input data
+	 * 
+	 * @param value Input String
+	 * @return Input String without newline characters
+	 */
+	public static String removeAllNewlineFromString(String value) {
+		return value.replaceAll("(\\t|\\r?\\n)+", "");
+		
+	}
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java
new file mode 100644
index 00000000..c752c91f
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ *******************************************************************************/
+
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import java.util.ListIterator;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Node;
+import org.w3c.dom.traversal.NodeFilter;
+import org.w3c.dom.traversal.NodeIterator;
+
+/**
+ * A <code>NodeIterator</code> implementation based on a
+ * <code>ListIterator</code>.
+ * 
+ * @see java.util.ListIterator
+ * @see org.w3c.dom.traversal.NodeIterator
+ * 
+ */
+public class NodeIteratorAdapter implements NodeIterator {
+
+  /** The <code>ListIterator</code> to wrap. */
+  private ListIterator nodeIterator;
+
+  /**
+   * Create a new <code>NodeIteratorAdapter</code>.
+   * @param nodeIterator The <code>ListIterator</code> to iterate over.
+   */
+  public NodeIteratorAdapter(ListIterator nodeIterator) {
+    this.nodeIterator = nodeIterator;
+  }
+
+  /**
+   * @see org.w3c.dom.traversal.NodeIterator#getRoot()
+   */
+  public Node getRoot() {
+    return null;
+  }
+
+  /**
+   * @see org.w3c.dom.traversal.NodeIterator#getWhatToShow()
+   */
+  public int getWhatToShow() {
+    return NodeFilter.SHOW_ALL;
+  }
+
+  /**
+   * @see org.w3c.dom.traversal.NodeIterator#getFilter()
+   */
+  public NodeFilter getFilter() {
+    return null;
+  }
+
+  /**
+   * @see org.w3c.dom.traversal.NodeIterator#getExpandEntityReferences()
+   */
+  public boolean getExpandEntityReferences() {
+    return false;
+  }
+
+  /**
+   * @see org.w3c.dom.traversal.NodeIterator#nextNode()
+   */
+  public Node nextNode() throws DOMException {
+    if (nodeIterator.hasNext()) {
+      return (Node) nodeIterator.next();
+    }
+    return null;
+  }
+
+  /**
+   * @see org.w3c.dom.traversal.NodeIterator#previousNode()
+   */
+  public Node previousNode() throws DOMException {
+    if (nodeIterator.hasPrevious()) {
+      return (Node) nodeIterator.previous();
+    }
+    return null;
+  }
+
+  /**
+   * @see org.w3c.dom.traversal.NodeIterator#detach()
+   */
+  public void detach() {
+  }
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java
new file mode 100644
index 00000000..61933907
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ *******************************************************************************/
+
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import java.util.List;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * A <code>NodeList</code> implementation based on a <code>List</code>.
+ * 
+ * @see java.util.List
+ * @see org.w3c.dom.NodeList
+ */
+
+public class NodeListAdapter implements NodeList {
+  /** The <code>List</code> to wrap. */
+  private List nodeList;
+  
+  /**
+   * Create a new <code>NodeListAdapter</code>.
+   * 
+   * @param nodeList The <code>List</code> containing the nodes. 
+   */
+  public NodeListAdapter(List nodeList) {
+    this.nodeList = nodeList;
+  }
+
+  /**
+   * @see org.w3c.dom.NodeList#item(int)
+   */
+  public Node item(int index) {
+    return (Node) nodeList.get(index);
+  }
+
+  /**
+   * @see org.w3c.dom.NodeList#getLength()
+   */
+  public int getLength() {
+    return nodeList.size();
+  }
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java
new file mode 100644
index 00000000..aad90649
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+
+import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.lang3.ArrayUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Random number generator used to generate ID's
+ * @author Paul Ivancsics
+ * @version $Id$
+ */
+public class Random {
+	private static final Logger log = LoggerFactory.getLogger(Random.class);
+	
+	private final static char[] allowedPreFix = 
+		{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
+		 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
+	private static final DateFormat dateFormater = new SimpleDateFormat("yyyyddMM");
+	
+  /** random number generator used */
+	private static SecureRandom random;
+	//private static SeedGenerator seedgenerator;	
+		
+	static {
+		try {
+			random = SecureRandom.getInstance("SHA256PRNG-FIPS186");
+			
+		} catch (NoSuchAlgorithmException e) {
+			log.warn("Can NOT initialize SecureRandom with: 'SHA256PRNG-FIPS186'. Use 'StrongSecureRandom' as backup");
+
+			try {
+				random = SecureRandom.getInstanceStrong();
+				
+			} catch (NoSuchAlgorithmException e1) {
+				log.error("Can NOT initialize SecureRandom. StartUp process FAILED!");
+				throw new RuntimeException("Can NOT initialize SecureRandom. StartUp process FAILED!", e);
+				
+			}
+			
+		}
+		
+		
+		//random = iaik.security.random.SHA256FIPS186Random.getDefault();		
+	}
+	
+	/**
+	 * Generate a unique process reference-value [160bit], which always starts with a letter
+	 * <br>
+	 * This unique ID consists of single letter, a 64bit date String[yyyyddMM],
+	 *  and a 88bit random value.  
+	 * 
+	 * @return 160bit ID, which is hex encoded
+	 */
+	public static String nextProcessReferenceValue() {		
+		//pre-process all three parts of a unique reference value
+		String now = dateFormater.format(new Date()); //8 bytes = 64bit
+		byte[] randValue = nextByteRandom(11);
+		char preFix = allowedPreFix[Math.abs(random.nextInt() % allowedPreFix.length)];
+	 
+		//generate ID
+		String returnValue = preFix + new String(Hex.encodeHex(ArrayUtils.addAll(now.getBytes(), randValue))); // 20 bytes = 160 bits
+		if (returnValue.length() > 40)
+			return returnValue.substring(0, 40);
+		else
+			return returnValue;
+			
+	}
+	
+	
+	
+	/**
+	 * Creates a new random number [256bit], and encode it as hex value.
+	 * 
+	 * @return random hex encoded value [256bit]
+	 */
+	public static String nextHexRandom32() {
+		return new String(Hex.encodeHex(nextByteRandom(32))); // 32 bytes = 256 bits
+		
+	}
+	
+	/**
+	 * Creates a new random number [128bit], and encode it as hex value.
+	 * 
+	 * @return random hex encoded value [128bit]
+	 */
+	public static String nextHexRandom16() {
+		return new String(Hex.encodeHex(nextByteRandom(16))); // 16 bytes = 128 bits
+		
+	}
+	
+	  /**
+	   * Creates a new random number [64bit], to be used as an ID.
+	   * 
+	   * @return random long as a String [64bit]
+	   */
+	public static String nextLongRandom() {	  
+		return "".concat(String.valueOf(Math.abs(generateLongRandom(32)))); // 32 bytes = 256 bits	
+			
+	  }
+		
+  /**
+   * Creates a new random number, to be used as an ID.
+   * 
+   * @return random long as a String [64bit]
+   */
+	@Deprecated
+  public static String nextRandom() {	  
+	long l = ByteBuffer.wrap(nextByteRandom(32)).getLong(); // 32 bytes = 256 bits
+	return "" + Math.abs(l);
+		
+  }
+  
+/**
+ * Creates a new random byte[]
+ * 	
+ * @param size Size of random number in byte
+ * @return
+ */
+public static byte[] nextBytes(int size) {
+	return  nextByteRandom(size);
+	
+}
+  
+  public static void seedRandom() {
+	  //TODO: implement reflection on IAIK Seed generator	  
+//      seedgenerator = iaik.security.random.AutoSeedGenerator.getDefault();  
+//	  if (seedgenerator.seedAvailable())
+//		  random.setSeed(seedgenerator.getSeed());
+	  
+	  random.setSeed(System.nanoTime());
+  }
+  
+	private static long generateLongRandom(int size) {
+		return ByteBuffer.wrap(nextByteRandom(size)).getLong(); 	
+	}
+  
+  /**
+   * Generate a new random number
+   * 
+   * @param size Size of random number in byte
+   * @return
+   */
+  private static synchronized byte[] nextByteRandom(int size) {
+	  byte[] b = new byte[size];
+	  random.nextBytes(b);			 
+	  return b;
+	  
+  }
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java
new file mode 100644
index 00000000..c19e5ab1
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+/**
+ * 
+ */
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class ServletUtils {
+  
+	
+  public static String getBaseUrl( HttpServletRequest request ) {
+	    if ( ( request.getServerPort() == 80 ) ||
+	         ( request.getServerPort() == 443 ) )
+	      return request.getScheme() + "://" +
+	             request.getServerName() +
+	             request.getContextPath();
+	    else
+	      return request.getScheme() + "://" +
+	             request.getServerName() + ":" + request.getServerPort() +
+	             request.getContextPath();
+	  }
+  
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java
new file mode 100644
index 00000000..3e4143d4
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ *******************************************************************************/
+
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+/**
+ * Utility methods for streams.
+ * 
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class StreamUtils {
+  
+  /**
+   * Compare the contents of two <code>InputStream</code>s.
+   * 
+   * @param is1 The 1st <code>InputStream</code> to compare.
+   * @param is2 The 2nd <code>InputStream</code> to compare.
+   * @return boolean <code>true</code>, if both streams contain the exactly the
+   * same content, <code>false</code> otherwise.
+   * @throws IOException An error occurred reading one of the streams.
+   */
+  public static boolean compareStreams(InputStream is1, InputStream is2) 
+    throws IOException {
+      
+    byte[] buf1 = new byte[256];
+    byte[] buf2 = new byte[256];
+    int length1;
+    int length2;
+  
+    try {
+      while (true) {
+        length1 = is1.read(buf1);
+        length2 = is2.read(buf2);
+        
+        if (length1 != length2) {
+          return false;
+        }
+        if (length1 <= 0) {
+          return true;
+        }
+        if (!compareBytes(buf1, buf2, length1)) {
+          return false;
+        }
+      }
+    } catch (IOException e) {
+      throw e;
+    } finally {
+      // close both streams
+      try {
+        is1.close();
+        is2.close();
+      } catch (IOException e) {
+        // ignore this
+      }
+    }
+  }
+  
+  /**
+   * Compare two byte arrays, up to a given maximum length.
+   * 
+   * @param b1 1st byte array to compare.
+   * @param b2 2nd byte array to compare.
+   * @param length The maximum number of bytes to compare.
+   * @return <code>true</code>, if the byte arrays are equal, <code>false</code>
+   * otherwise.
+   */
+  private static boolean compareBytes(byte[] b1, byte[] b2, int length) {
+    if (b1.length != b2.length) {
+      return false;
+    }
+  
+    for (int i = 0; i < b1.length && i < length; i++) {
+      if (b1[i] != b2[i]) {
+        return false;
+      }
+    }
+  
+    return true;
+  }
+
+  /**
+   * Reads a byte array from a stream.
+   * @param in The <code>InputStream</code> to read.
+   * @return The bytes contained in the given <code>InputStream</code>.
+   * @throws IOException on any exception thrown
+   */
+  public static byte[] readStream(InputStream in) throws IOException {
+
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    copyStream(in, out, null);
+		  
+		/*  
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    int b;
+    while ((b = in.read()) >= 0)
+      out.write(b);
+    
+    */
+    in.close();
+    return out.toByteArray();
+  }
+
+  /**
+   * Reads a <code>String</code> from a stream, using given encoding.
+   * @param in The <code>InputStream</code> to read.
+   * @param encoding The character encoding to use for converting the bytes
+   * of the <code>InputStream</code> into a <code>String</code>.
+   * @return The content of the given <code>InputStream</code> converted into
+   * a <code>String</code>.
+   * @throws IOException on any exception thrown
+   */
+  public static String readStream(InputStream in, String encoding) throws IOException {
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    copyStream(in, out, null);
+
+    /*
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    int b;
+    while ((b = in.read()) >= 0)
+      out.write(b);
+      */
+    in.close();
+    return out.toString(encoding);
+  }
+  
+  /**
+   * Reads all data (until EOF is reached) from the given source to the 
+   * destination stream. If the destination stream is null, all data is dropped.
+   * It uses the given buffer to read data and forward it. If the buffer is 
+   * null, this method allocates a buffer.
+   *
+   * @param source The stream providing the data.
+   * @param destination The stream that takes the data. If this is null, all
+   *                    data from source will be read and discarded.
+   * @param buffer The buffer to use for forwarding. If it is null, the method
+   *               allocates a buffer.
+   * @exception IOException If reading from the source or writing to the 
+   *                        destination fails.
+   */
+  private static void copyStream(InputStream source, OutputStream destination, byte[] buffer) throws IOException {
+    if (source == null) {
+      throw new NullPointerException("Argument \"source\" must not be null.");
+    }
+    if (buffer == null) {
+      buffer = new byte[8192];
+    }
+    
+    if (destination != null) {
+      int bytesRead;
+      while ((bytesRead = source.read(buffer)) >= 0) {
+        destination.write(buffer, 0, bytesRead);
+      }
+    } else {
+      while (source.read(buffer) >= 0);
+    }    
+  }
+  
+  /**
+   * Gets the stack trace of the <code>Throwable</code> passed in as a string.
+   * @param t The <code>Throwable</code>.
+   * @return a String representing the stack trace of the <code>Throwable</code>.
+   */
+  public static String getStackTraceAsString(Throwable t)
+  {
+    ByteArrayOutputStream stackTraceBIS = new ByteArrayOutputStream();
+    t.printStackTrace(new PrintStream(stackTraceBIS));
+    return new String(stackTraceBIS.toByteArray());
+  }
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIDUtils.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIDUtils.java
new file mode 100644
index 00000000..7df211ef
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIDUtils.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.utils;
+
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+
+/**
+ * @author tlenz
+ *
+ */
+public class TransactionIDUtils {
+
+	  //MDC variables for logging
+	  public static final String MDC_TRANSACTION_ID = "transactionId";
+	  public static final String MDC_SESSION_ID = "sessionId";
+	  public static final String MDC_SERVICEPROVIDER_ID = "oaId";
+	
+	/**
+	 * Set all MDC variables from pending request to this threat context<br>
+	 * These includes SessionID, TransactionID, and unique service-provider identifier
+	 * 
+	 * @param pendingRequest
+	 */
+	public static void setAllLoggingVariables(IRequest pendingRequest) {
+		setTransactionId(pendingRequest.getUniqueTransactionIdentifier());
+		setSessionId(pendingRequest.getUniqueSessionIdentifier());
+		setServiceProviderId(pendingRequest.getServiceProviderConfiguration().getUniqueIdentifier());
+		
+	}
+	
+	/**
+	 * Remove all MDC variables from this threat context
+	 * 
+	 */
+	public static void removeAllLoggingVariables() {
+		removeSessionId();
+		removeTransactionId();
+		removeServiceProviderId();
+		
+	}
+	
+	
+	public static void setServiceProviderId(String oaUniqueId) {
+		org.apache.log4j.MDC.put(MDC_SERVICEPROVIDER_ID, oaUniqueId);		
+		org.slf4j.MDC.put(MDC_SERVICEPROVIDER_ID, oaUniqueId);
+		
+	}
+	
+	public static void removeServiceProviderId() {
+		org.apache.log4j.MDC.remove(MDC_SERVICEPROVIDER_ID);
+		org.slf4j.MDC.remove(MDC_SERVICEPROVIDER_ID);
+		
+	}
+	
+	public static void setTransactionId(String pendingRequestID) {	  
+		org.apache.log4j.MDC.put(MDC_TRANSACTION_ID, 
+				"TID-" + pendingRequestID);		
+		org.slf4j.MDC.put(MDC_TRANSACTION_ID, 
+				"TID-" + pendingRequestID);
+				    
+	}
+		
+	public static void removeTransactionId() {
+		org.apache.log4j.MDC.remove(MDC_TRANSACTION_ID);
+		org.slf4j.MDC.remove(MDC_TRANSACTION_ID);
+		
+	}
+		
+	public static void setSessionId(String uniqueSessionId) {	  
+		org.apache.log4j.MDC.put(MDC_SESSION_ID, 
+				"SID-" + uniqueSessionId);		
+		org.slf4j.MDC.put(MDC_SESSION_ID, 
+				"SID-" + uniqueSessionId);
+				    
+	}
+		
+	public static void removeSessionId() {
+		org.apache.log4j.MDC.remove(MDC_SESSION_ID);
+		org.slf4j.MDC.remove(MDC_SESSION_ID);
+		
+	}
+	
+	
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/XPathUtils.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/XPathUtils.java
new file mode 100644
index 00000000..7df242bd
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/XPathUtils.java
@@ -0,0 +1,523 @@
+/*******************************************************************************
+ *******************************************************************************/
+
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jaxen.JaxenException;
+import org.jaxen.NamespaceContext;
+import org.jaxen.Navigator;
+import org.jaxen.SimpleNamespaceContext;
+import org.jaxen.dom.DOMXPath;
+import org.jaxen.dom.DocumentNavigator;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.traversal.NodeIterator;
+
+import at.gv.egiz.eaaf.core.api.data.XMLNamespaceConstants;
+import at.gv.egiz.eaaf.core.exceptions.XPathException;
+
+/**
+ * Utility methods to evaluate XPath expressions on DOM nodes.
+ * 
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XPathUtils {
+
+  /**
+   * The XPath expression selecting all nodes under a given root (including the
+   * root node itself).
+   */
+  public static final String ALL_NODES_XPATH =
+    "(.//. | .//@* | .//namespace::*)";
+
+  /** The <code>DocumentNavigator</code> to use for navigating the document. */
+  private static Navigator documentNavigator =
+    DocumentNavigator.getInstance();
+  /** The default namespace prefix to namespace URI mappings. */
+  private static NamespaceContext NS_CONTEXT;
+ 
+  static { 
+    SimpleNamespaceContext ctx = new SimpleNamespaceContext();
+    ctx.addNamespace(XMLNamespaceConstants.MOA_PREFIX, XMLNamespaceConstants.MOA_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.MOA_CONFIG_PREFIX, XMLNamespaceConstants.MOA_CONFIG_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.MOA_ID_CONFIG_PREFIX, XMLNamespaceConstants.MOA_ID_CONFIG_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.SL10_PREFIX, XMLNamespaceConstants.SL10_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.SL11_PREFIX, XMLNamespaceConstants.SL11_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.SL12_PREFIX, XMLNamespaceConstants.SL12_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.ECDSA_PREFIX, XMLNamespaceConstants.ECDSA_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.PD_PREFIX, XMLNamespaceConstants.PD_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.SAML_PREFIX, XMLNamespaceConstants.SAML_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.SAMLP_PREFIX, XMLNamespaceConstants.SAMLP_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.DSIG_PREFIX, XMLNamespaceConstants.DSIG_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.XSLT_PREFIX, XMLNamespaceConstants.XSLT_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.XSI_PREFIX, XMLNamespaceConstants.XSI_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.DSIG_FILTER2_PREFIX, XMLNamespaceConstants.DSIG_FILTER2_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.DSIG_EC_PREFIX, XMLNamespaceConstants.DSIG_EC_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.MD_PREFIX, XMLNamespaceConstants.MD_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.MDP_PREFIX, XMLNamespaceConstants.MDP_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.MVV_PREFIX, XMLNamespaceConstants.MVV_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.STB_PREFIX, XMLNamespaceConstants.STB_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.WRR_PREFIX, XMLNamespaceConstants.WRR_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.STORK_PREFIX, XMLNamespaceConstants.STORK_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.STORKP_PREFIX, XMLNamespaceConstants.STORKP_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.SAML2_PREFIX, XMLNamespaceConstants.SAML2_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.SAML2P_PREFIX, XMLNamespaceConstants.SAML2P_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.XENC_PREFIX, XMLNamespaceConstants.XENC_NS_URI);
+    ctx.addNamespace(XMLNamespaceConstants.XADES_1_1_1_NS_PREFIX, XMLNamespaceConstants.XADES_1_1_1_NS_URI);
+    NS_CONTEXT = ctx;
+  }
+
+  /**
+   * Return a <code>NodeIterator</code> over the nodes matching the XPath
+   * expression.
+   * 
+   * All namespace URIs and prefixes declared in the <code>Constants</code>
+   * interface are used for resolving namespaces.
+   * 
+   * @param contextNode The root node from which to evaluate the XPath
+   * expression.
+   * @param exp The XPath expression to evaluate.
+   * @return An iterator over the resulting nodes.
+   * @throws XPathException An error occurred evaluating the XPath expression.
+   */
+  public static NodeIterator selectNodeIterator(Node contextNode, String exp)
+    throws XPathException {
+
+    return selectNodeIterator(contextNode, NS_CONTEXT, exp);
+  }
+
+  /**
+   * Return a <code>NodeIterator</code> over the nodes matching the XPath
+   * expression.
+   * 
+   * @param contextNode The root node from which to evaluate the XPath
+   * expression.
+   * @param namespaceElement An element from which to build the
+   * namespace mapping for evaluating the XPath expression
+   * @param exp The XPath expression to evaluate.
+   * @return An iterator over the resulting nodes.
+   * @throws XPathException An error occurred evaluating the XPath expression.
+   */
+  public static NodeIterator selectNodeIterator(
+    Node contextNode,
+    Element namespaceElement,
+    String exp)
+    throws XPathException {
+
+    try {
+      SimpleNamespaceContext ctx = new SimpleNamespaceContext();
+      ctx.addElementNamespaces(documentNavigator, namespaceElement);
+      return selectNodeIterator(contextNode, ctx, exp);
+      
+    } catch (JaxenException e) {
+    	throw new XPathException("XPath operation FAILED. Reason: " + e.getMessage(), e);
+    	
+    }
+  }
+
+  /**
+   * Return a <code>NodeIterator</code> over the nodes matching the XPath
+   * expression.
+   * 
+   * @param contextNode The root node from which to evaluate the XPath
+   * expression.
+   * @param namespaceMapping A namespace prefix to namespace URI mapping
+   * (<code>String</code> to <code>String</code>) for evaluating the XPath 
+   * expression.
+   * @param exp The XPath expression to evaluate.
+   * @return An iterator over the resulting nodes.
+   * @throws XPathException An error occurred evaluating the XPath expression.
+   */
+  public static NodeIterator selectNodeIterator(
+    Node contextNode,
+    Map namespaceMapping,
+    String exp)
+    throws XPathException {
+
+    SimpleNamespaceContext ctx = new SimpleNamespaceContext(namespaceMapping);
+
+    return selectNodeIterator(contextNode, ctx, exp);
+  }
+
+  /**
+   * Return a <code>NodeIterator</code> over the nodes matching the XPath
+   * expression.
+   * 
+   * @param contextNode The root node from which to evaluate the XPath
+   * expression.
+   * @param nsContext The <code>NamespaceContext</code> for resolving namespace
+   * prefixes to namespace URIs for evaluating the XPath expression.
+   * @param exp The XPath expression to evaluate.
+   * @return An iterator over the resulting nodes.
+   * @throws XPathException An error occurred evaluating the XPath expression.
+   */
+  private static NodeIterator selectNodeIterator(
+    Node contextNode,
+    NamespaceContext nsContext,
+    String exp)
+    throws XPathException {
+
+    try {
+      DOMXPath xpath = new DOMXPath(exp);
+      List nodes;
+
+      xpath.setNamespaceContext(nsContext);
+      nodes = xpath.selectNodes(contextNode);
+      return new NodeIteratorAdapter(nodes.listIterator());
+      
+    } catch (JaxenException e) {
+    	throw new XPathException("XPath operation FAILED. Reason: " + e.getMessage(), e);
+    	
+    }
+  }
+
+  /**
+   * Return a <code>NodeList</code> of all the nodes matching the XPath
+   * expression.
+   * 
+   * All namespace URIs and prefixes declared in the <code>Constants</code>
+   * interface are used for resolving namespaces.
+   * 
+   * @param contextNode The root node from which to evaluate the XPath
+   * expression.
+   * @param exp The XPath expression to evaluate.
+   * @return A <code>NodeList</code> containing the matching nodes.
+   * @throws XPathException An error occurred evaluating the XPath expression.
+   */
+  public static NodeList selectNodeList(Node contextNode, String exp)
+    throws XPathException {
+
+    return selectNodeList(contextNode, NS_CONTEXT, exp);
+  }
+
+  /**
+   * Return a <code>NodeList</code> of all the nodes matching the XPath
+   * expression.
+   * 
+   * @param contextNode The root node from which to evaluate the XPath
+   * expression.
+   * @param namespaceElement An element from which to build the
+   * namespace mapping for evaluating the XPath expression
+   * @param exp The XPath expression to evaluate.
+   * @return A <code>NodeList</code> containing the matching nodes.
+   * @throws XPathException An error occurred evaluating the XPath expression.
+   */
+  public static NodeList selectNodeList(
+    Node contextNode,
+    Element namespaceElement,
+    String exp)
+    throws XPathException {
+
+    try {
+      SimpleNamespaceContext ctx = new SimpleNamespaceContext();
+
+      ctx.addElementNamespaces(documentNavigator, namespaceElement);
+      return selectNodeList(contextNode, ctx, exp);
+      
+    } catch (JaxenException e) {
+    	throw new XPathException("XPath operation FAILED. Reason: " + e.getMessage(), e);
+    	
+    }
+  }
+
+  /**
+   * Return a <code>NodeList</code> of all the nodes matching the XPath
+   * expression.
+   * 
+   * @param contextNode The root node from which to evaluate the XPath
+   * expression.
+   * @param namespaceMapping A namespace prefix to namespace URI mapping
+   * (<code>String</code> to <code>String</code>) for evaluating the XPath 
+   * expression.
+   * @param exp The XPath expression to evaluate.
+   * @return A <code>NodeList</code> containing the matching nodes.
+   * @throws XPathException An error occurred evaluating the XPath expression.
+   */
+  public static NodeList selectNodeList(
+    Node contextNode,
+    Map namespaceMapping,
+    String exp)
+    throws XPathException {
+
+    SimpleNamespaceContext ctx = new SimpleNamespaceContext(namespaceMapping);
+
+    return selectNodeList(contextNode, ctx, exp);
+  }
+
+  /**
+   * Return a <code>NodeList</code> of all the nodes matching the XPath
+   * expression.
+   * 
+   * @param contextNode The root node from which to evaluate the XPath
+   * expression.
+   * @param nsContext The <code>NamespaceContext</code> for resolving namespace
+   * prefixes to namespace URIs for evaluating the XPath expression.
+   * @param exp The XPath expression to evaluate.
+   * @return A <code>NodeList</code> containing the matching nodes.
+   * @throws XPathException An error occurred evaluating the XPath expression.
+   */
+  private static NodeList selectNodeList(Node contextNode, NamespaceContext nsContext, String exp) throws XPathException {
+	  try {
+		  DOMXPath xpath = new DOMXPath(exp);
+		  List nodes;
+		  xpath.setNamespaceContext(nsContext);
+		  nodes = xpath.selectNodes(contextNode);
+		  return new NodeListAdapter(nodes);
+      
+	  } catch (JaxenException e) {
+		  throw new XPathException("XPath operation FAILED. Reason: " + e.getMessage(), e);
+    	
+	  }
+  }
+
+  /**
+   * Select the first node matching an XPath expression.
+   * 
+   * All namespace URIs and prefixes declared in the <code>Constants</code>
+   * interface are used for resolving namespaces.
+   * 
+   * @param contextNode The root node from which to evaluate the XPath
+   * expression.
+   * @param exp The XPath expression to evaluate.
+   * @return Node The first node matching the XPath expression, or
+   * <code>null</code>, if no node matched.
+   * @throws XPathException An error occurred evaluating the XPath expression.
+   */
+  public static Node selectSingleNode(Node contextNode, String exp)
+    throws XPathException {
+
+    return selectSingleNode(contextNode, NS_CONTEXT, exp);
+  }
+
+  /**
+   * Select the first node matching an XPath expression.
+   * 
+   * @param contextNode The root node from which to evaluate the XPath
+   * expression.
+   * @param namespaceElement An element from which to build the
+   * namespace mapping for evaluating the XPath expression
+   * @param exp The XPath expression to evaluate.
+   * @return Node The first node matching the XPath expression, or
+   * <code>null</code>, if no node matched.
+   * @throws XPathException An error occurred evaluating the XPath expression.
+   */
+  public static Node selectSingleNode(
+    Node contextNode,
+    Element namespaceElement,
+    String exp)
+    throws XPathException {
+
+    try {
+      SimpleNamespaceContext ctx = new SimpleNamespaceContext();
+      ctx.addElementNamespaces(documentNavigator, namespaceElement);
+      return selectSingleNode(contextNode, ctx, exp);
+      
+    } catch (JaxenException e) {    	
+    	throw new XPathException("XPath operation FAILED. Reason: " + e.getMessage(), e);
+    	
+    }
+  }
+
+  /**
+   * Select the first node matching an XPath expression.
+   * 
+   * @param contextNode The root node from which to evaluate the XPath
+   * expression.
+   * @param namespaceMapping A namespace prefix to namespace URI mapping
+   * (<code>String</code> to <code>String</code>) for evaluating the XPath 
+   * expression.
+   * @param exp The XPath expression to evaluate.
+   * @return Node The first node matching the XPath expression, or
+   * <code>null</code>, if no node matched.
+   * @throws XPathException An error occurred evaluating the XPath expression.
+   */
+  public static Node selectSingleNode(
+    Node contextNode,
+    Map namespaceMapping,
+    String exp)
+    throws XPathException {
+
+    SimpleNamespaceContext ctx = new SimpleNamespaceContext(namespaceMapping);
+
+    return selectSingleNode(contextNode, ctx, exp);
+  }
+
+  /**
+   * Select the first node matching an XPath expression.
+   * 
+   * @param contextNode The root node from which to evaluate the XPath
+   * expression.
+   * @param nsContext The <code>NamespaceContext</code> for resolving namespace
+   * prefixes to namespace URIs for evaluating the XPath expression.
+   * @param exp The XPath expression to evaluate.
+   * @return Node The first node matching the XPath expression, or
+   * <code>null</code>, if no node matched.
+   * @throws XPathException An error occurred evaluating the XPath expression.
+   */
+  public static Node selectSingleNode(
+    Node contextNode,
+    NamespaceContext nsContext,
+    String exp)
+    throws XPathException {
+
+    try {
+      DOMXPath xpath = new DOMXPath(exp);
+      xpath.setNamespaceContext(nsContext);
+      return (Node) xpath.selectSingleNode(contextNode);
+      
+    } catch (JaxenException e) {
+    	throw new XPathException("XPath operation FAILED. Reason: " + e.getMessage(), e);
+    	
+    }
+  }
+
+  /**
+   * Return the value of a DOM element whose location is given by an XPath
+   * expression.
+   * 
+   * @param root The root element from which to evaluate the XPath.
+   * @param xpath The XPath expression pointing to the element whose value
+   * to return.
+   * @param def The default value to return, if no element can be found using
+   * the given <code>xpath</code>.
+   * @return The element value, if it can be located using the
+   * <code>xpath</code>. Otherwise, <code>def</code> is returned.
+   */
+  public static String getElementValue(
+    Element root,
+    String xpath,
+    String def) {
+
+    Element elem = (Element) XPathUtils.selectSingleNode(root, xpath);
+    return elem != null ? DOMUtils.getText(elem) : def;
+  }
+
+  /**
+   * Return the value of a DOM attribute whose location is given by an XPath
+   * expression.
+   * 
+   * @param root The root element from which to evaluate the XPath.
+   * @param xpath The XPath expression pointing to the attribute whose value to
+   * return.
+   * @param def The default value to return, if no attribute can be found using
+   * the given <code>xpath</code>.
+   * @return The element value, if it can be located using the
+   * <code>xpath</code>. Otherwise, <code>def</code> is returned.
+   */
+  public static String getAttributeValue(
+    Element root,
+    String xpath,
+    String def) {
+
+    Attr attr = (Attr) XPathUtils.selectSingleNode(root, xpath);
+    return attr != null ? attr.getValue() : def;
+  }
+  
+  /**
+   * Returns the namespace prefix used within <code>XPathUtils</code> for referring to
+   * the namespace of the specified (Security Layer command) element.
+   * 
+   * This namespace prefix can be used in various XPath expression evaluation methods 
+   * within <code> XPathUtils</code> without explicitely binding it to the particular
+   * namespace.
+   * 
+   * @param contextElement The (Security Layer command) element. 
+   *            
+   * @return  the namespace prefix used within <code>XPathUtils</code> for referring to
+   *          the namespace of the specified (Security Layer command) element.
+   * 
+   * throws XpathException If the specified element has a namespace other than the ones
+   *        known by this implementation as valid Security Layer namespaces (cf. 
+   *        @link Constants#SL10_NS_URI, @link Constants#SL11_NS_URI, @link Constants#SL12_NS_URI).
+   */
+  public static String getSlPrefix (Element contextElement) throws XPathException 
+  {
+    String sLNamespace = contextElement.getNamespaceURI();
+    String sLPrefix = null;
+
+    if (sLNamespace.equals(XMLNamespaceConstants.SL10_NS_URI)) 
+    	sLPrefix = XMLNamespaceConstants.SL10_PREFIX;
+    
+    else if (sLNamespace.equals(XMLNamespaceConstants.SL12_NS_URI)) 
+    	sLPrefix = XMLNamespaceConstants.SL12_PREFIX;
+    
+    else if (sLNamespace.equals(XMLNamespaceConstants.SL11_NS_URI)) 
+    	sLPrefix = XMLNamespaceConstants.SL11_PREFIX;
+    
+    else 
+    	throw new XPathException("XPath operation FAILED. Reason: ");
+    	
+    return sLPrefix;
+  }
+  
+  
+  /**
+   * Return the SecurityLayer namespace prefix of the context element.
+   * If the context element is not the element that lies within the 
+   * SecurityLayer namespace. The Securitylayer namespace is derived from
+   * the <code>xmlns:sl10</code>, <code>sl11</code> or <code>sl</code> 
+   * attribute of the context element.
+   * 
+   * The returned prefix is needed for evaluating XPATH expressions.
+   * 
+   * @param contextElement The element to get a prefix for the Securitylayer namespace,
+   *                       that is used within the corresponding document. 
+   *            
+   * @return  The string <code>sl10</code>, <code>sl11</code> or <code>sl</code>,
+   *          depending on the SecurityLayer namespace of the contextElement.
+   * 
+   * throws XPathException If no (vlalid) SecurityLayer namespace prefix or namespace
+   *                       is defined.
+   */
+  public static String getSlPrefixFromNoRoot (Element contextElement) throws XPathException {
+    
+    String slPrefix = checkSLnsDeclaration(contextElement, XMLNamespaceConstants.SL10_PREFIX, XMLNamespaceConstants.SL10_NS_URI);
+    if (slPrefix == null)
+    	slPrefix = checkSLnsDeclaration(contextElement, XMLNamespaceConstants.SL11_PREFIX, XMLNamespaceConstants.SL11_NS_URI);
+    
+    if (slPrefix == null)
+    	slPrefix = checkSLnsDeclaration(contextElement, XMLNamespaceConstants.SL12_PREFIX, XMLNamespaceConstants.SL12_NS_URI);
+     
+    return slPrefix;
+       
+  }
+  
+  /**
+   * Checks if the context element has an attribute <code>xmlns:slPrefix</code> and
+   * if the prefix of that attribute corresponds with a valid SecurityLayer namespace.
+   * 
+   * @param contextElement  The element to be checked.
+   * @param slPrefix        The prefix which should be checked. Must be a valid SecurityLayer
+   *                        namespace prefix.
+   * @param slNameSpace     The SecurityLayer namespace that corresponds to the specified prefix.
+   *  
+   * @return                The valid SecurityLayer prefix or <code>null</code> if this prefix is
+   *                        not used.
+   * @throws XPathException
+   */
+  private static String checkSLnsDeclaration(Element contextElement, String slPrefix, String slNameSpace)
+      throws XPathException 
+  {
+    String nsAtt = "xmlns:" + slPrefix;
+    String nameSpace = contextElement.getAttribute(nsAtt);
+    if (nameSpace == "") {
+      return null;
+      
+    } else {
+      // check if namespace is correct
+      if (nameSpace.equals(slNameSpace))
+        return slPrefix;
+      else
+    	throw new XPathException("Unknown Namespace declaration");
+
+    }
+  }
+
+}
-- 
cgit v1.2.3