From b1c8641a63a67e3c64d948f9e8dce5c01e11e2dd Mon Sep 17 00:00:00 2001
From: mcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>
Date: Wed, 5 May 2010 15:29:01 +0000
Subject: Merged feature branch mocca-1.2.13-id@r724 back to trunk.

git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@725 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
---
 .../accesscontroller/AccessControllerFactory.java  | 305 ++++---
 .../accesscontroller/AuthenticationClassifier.java | 220 ++---
 .../gv/egiz/bku/accesscontroller/ChainChecker.java | 183 ++---
 .../bku/accesscontroller/InfoboxParamChecker.java  | 149 ++--
 .../gv/egiz/bku/accesscontroller/RuleChecker.java  | 406 +++++-----
 .../accesscontroller/SecurityManagerFacade.java    | 237 +++---
 .../egiz/bku/binding/AbstractBindingProcessor.java | 111 ++-
 .../binding/AbstractBindingProcessorFactory.java   |  81 ++
 .../at/gv/egiz/bku/binding/BindingProcessor.java   | 153 +++-
 .../egiz/bku/binding/BindingProcessorFactory.java  |  42 +
 .../egiz/bku/binding/BindingProcessorFuture.java   |  73 ++
 .../egiz/bku/binding/BindingProcessorManager.java  | 138 ++--
 .../bku/binding/BindingProcessorManagerImpl.java   | 414 +++++-----
 .../egiz/bku/binding/DataURLConnectionFactory.java |  26 +
 .../main/java/at/gv/egiz/bku/binding/DataUrl.java  |  91 +--
 .../at/gv/egiz/bku/binding/DataUrlConnection.java  | 134 +--
 .../gv/egiz/bku/binding/DataUrlConnectionImpl.java | 340 +++-----
 .../gv/egiz/bku/binding/DataUrlConnectionSPI.java  |  64 --
 .../java/at/gv/egiz/bku/binding/ExpiryRemover.java |  67 --
 .../egiz/bku/binding/FormDataURLDereferencer.java  |  71 ++
 .../gv/egiz/bku/binding/FormDataURLSupplier.java   |  27 +
 .../gv/egiz/bku/binding/HTTPBindingProcessor.java  | 859 +-------------------
 .../bku/binding/HTTPBindingProcessorFactory.java   |  80 ++
 .../egiz/bku/binding/HTTPBindingProcessorImpl.java | 896 +++++++++++++++++++++
 .../gv/egiz/bku/binding/HttpDataURLConnection.java |  68 ++
 .../main/java/at/gv/egiz/bku/binding/HttpUtil.java |   3 +-
 .../egiz/bku/binding/HttpsDataURLConnection.java   |  72 ++
 .../java/at/gv/egiz/bku/binding/IdFactory.java     | 180 ++---
 .../main/java/at/gv/egiz/bku/binding/IdImpl.java   |  11 +-
 .../gv/egiz/bku/binding/InputDecoderFactory.java   | 148 ++--
 .../bku/binding/MultiPartFormDataInputDecoder.java | 235 +++---
 .../at/gv/egiz/bku/binding/ProcessingContext.java  |  59 --
 .../at/gv/egiz/bku/binding/RemovalStrategy.java    |  26 -
 .../gv/egiz/bku/binding/SLCommandInvokerImpl.java  |  33 +-
 .../egiz/bku/binding/XWWWFormUrlInputIterator.java |   1 +
 .../java/at/gv/egiz/bku/conf/CertValidator.java    |  13 -
 .../at/gv/egiz/bku/conf/CertValidatorImpl.java     | 110 ---
 .../java/at/gv/egiz/bku/conf/Configuration.java    | 100 ---
 .../java/at/gv/egiz/bku/conf/Configurator.java     | 467 -----------
 .../java/at/gv/egiz/bku/conf/IAIKCommonsLog.java   | 144 ----
 .../at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java |  59 --
 .../java/at/gv/egiz/bku/conf/IAIKLogAdapter.java   | 146 ++++
 .../at/gv/egiz/bku/conf/IAIKLogAdapterFactory.java |  62 ++
 .../gv/egiz/bku/conf/MoccaConfigurationFacade.java |  22 +
 .../java/at/gv/egiz/bku/jmx/ComponentMXBean.java   |  27 +
 .../java/at/gv/egiz/bku/jmx/ComponentState.java    |  38 +
 .../at/gv/egiz/bku/jmx/ComponentStateCheck.java    |  24 +
 .../bku/slcommands/AbstractSLCommandFactory.java   |  46 ++
 .../bku/slcommands/CreateXMLSignatureCommand.java  |   2 +-
 .../bku/slcommands/CreateXMLSignatureResult.java   |   7 +-
 .../at/gv/egiz/bku/slcommands/ErrorResult.java     |   8 +-
 .../gv/egiz/bku/slcommands/InfoboxReadResult.java  |   5 +-
 .../java/at/gv/egiz/bku/slcommands/SLCommand.java  |  10 +-
 .../gv/egiz/bku/slcommands/SLCommandContext.java   |  31 +-
 .../gv/egiz/bku/slcommands/SLCommandFactory.java   | 519 ++++--------
 .../gv/egiz/bku/slcommands/SLCommandInvoker.java   |   2 +-
 .../egiz/bku/slcommands/SLMarshallerFactory.java   |  11 +-
 .../at/gv/egiz/bku/slcommands/SLSourceContext.java |   3 -
 .../slcommands/impl/AbstractAssocArrayInfobox.java |  16 +-
 .../slcommands/impl/AbstractBinaryFileInfobox.java |   8 +-
 .../impl/AbstractInfoboxCommandFactory.java        |  40 +
 .../impl/AbstractInfoboxCommandImpl.java           |  26 +-
 .../slcommands/impl/AbstractInfoboxFactory.java    |  24 +
 .../slcommands/impl/CardChannelInfoboxFactory.java |  27 +
 .../slcommands/impl/CardChannelInfoboxImpl.java    |  12 +-
 .../impl/CertificatesInfoboxFactory.java           |  27 +
 .../slcommands/impl/CertificatesInfoboxImpl.java   |   6 +-
 .../impl/CreateXMLSignatureCommandFactory.java     |  65 ++
 .../impl/CreateXMLSignatureCommandImpl.java        |  77 +-
 .../impl/CreateXMLSignatureResultImpl.java         |  27 +-
 .../impl/DomCreateXMLSignatureResultImpl.java      |  47 ++
 .../bku/slcommands/impl/DomErrorResultImpl.java    |  70 ++
 .../slcommands/impl/DomInfoboxReadResultImpl.java  | 105 +++
 .../gv/egiz/bku/slcommands/impl/DomSLResult.java   |  41 +
 .../egiz/bku/slcommands/impl/ErrorResultImpl.java  |  18 +
 .../slcommands/impl/GetStatusCommandFactory.java   |  37 +
 .../bku/slcommands/impl/GetStatusCommandImpl.java  |  24 +-
 .../impl/IdentityLinkInfoboxFactory.java           |  48 ++
 .../slcommands/impl/IdentityLinkInfoboxImpl.java   |  28 +-
 .../egiz/bku/slcommands/impl/InfoboxFactory.java   | 103 +--
 .../slcommands/impl/InfoboxReadCommandFactory.java |  37 +
 .../slcommands/impl/InfoboxReadCommandImpl.java    |  84 +-
 .../slcommands/impl/InfoboxReadResultFileImpl.java |  40 +-
 .../bku/slcommands/impl/InfoboxReadResultImpl.java |  18 +
 .../impl/InfoboxUpdateCommandFactory.java          |  37 +
 .../slcommands/impl/InfoboxUpdateCommandImpl.java  |  16 +-
 .../impl/NullOperationCommandFactory.java          |  37 +
 .../slcommands/impl/NullOperationCommandImpl.java  |   3 +-
 .../gv/egiz/bku/slcommands/impl/SLCommandImpl.java |  33 +-
 .../gv/egiz/bku/slcommands/impl/SLResultImpl.java  |  18 +-
 .../at/gv/egiz/bku/slcommands/impl/STALHelper.java |  17 +-
 .../impl/SVPersonendatenInfoboxFactory.java        |  27 +
 .../impl/SVPersonendatenInfoboxImpl.java           |  10 +-
 .../impl/xsect/AlgorithmMethodFactoryImpl.java     |   3 +-
 .../egiz/bku/slcommands/impl/xsect/DataObject.java | 191 +++--
 .../slcommands/impl/xsect/LocRefDereferencer.java  | 189 +++--
 .../bku/slcommands/impl/xsect/STALPrivateKey.java  |   3 +-
 .../bku/slcommands/impl/xsect/STALProvider.java    |  71 --
 .../bku/slcommands/impl/xsect/STALSignature.java   | 184 -----
 .../impl/xsect/STALSignatureException.java         |   2 +-
 .../slcommands/impl/xsect/STALSignatureMethod.java | 127 +++
 .../egiz/bku/slcommands/impl/xsect/Signature.java  |  43 +-
 .../slcommands/impl/xsect/SignatureContext.java    |  50 +-
 .../slcommands/impl/xsect/SignatureLocation.java   | 418 +++++-----
 .../impl/xsect/URIDereferncerAdapter.java          |  14 +-
 .../egiz/bku/slexceptions/SLBindingException.java  |   2 +
 .../egiz/bku/slexceptions/SLCanceledException.java |   2 +
 .../at/gv/egiz/bku/slexceptions/SLException.java   |   9 +-
 .../egiz/bku/slexceptions/SLRequestException.java  |   2 +
 .../egiz/bku/slexceptions/SLRuntimeException.java  |   2 +
 .../egiz/bku/slexceptions/SLViewerException.java   |   2 +
 .../bku/spring/ConfigurableHostnameVerifier.java   |  77 ++
 .../egiz/bku/spring/ConfigurationFactoryBean.java  | 172 ++++
 .../gv/egiz/bku/spring/PKIProfileFactoryBean.java  | 235 ++++++
 .../at/gv/egiz/bku/spring/PKITrustManager.java     | 173 ++++
 .../gv/egiz/bku/spring/SSLSocketFactoryBean.java   | 109 +++
 .../bku/spring/SecurityManagerFactoryBean.java     | 102 +++
 .../at/gv/egiz/bku/viewer/ResourceFontLoader.java  |   6 +-
 .../at/gv/egiz/bku/viewer/ValidatorFactory.java    |  22 +-
 119 files changed, 6244 insertions(+), 5078 deletions(-)
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessorFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFuture.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/DataURLConnectionFactory.java
 delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionSPI.java
 delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/ExpiryRemover.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLDereferencer.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLSupplier.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorImpl.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpDataURLConnection.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpsDataURLConnection.java
 delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/ProcessingContext.java
 delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/RemovalStrategy.java
 delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidator.java
 delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java
 delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/Configuration.java
 delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java
 delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java
 delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapter.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapterFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/MoccaConfigurationFacade.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentMXBean.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentState.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentStateCheck.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/AbstractSLCommandFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomCreateXMLSignatureResultImpl.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomErrorResultImpl.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomInfoboxReadResultImpl.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomSLResult.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandFactory.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxFactory.java
 delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java
 delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignature.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureMethod.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurableHostnameVerifier.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurationFactoryBean.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/spring/PKIProfileFactoryBean.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/spring/PKITrustManager.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/spring/SSLSocketFactoryBean.java
 create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/spring/SecurityManagerFactoryBean.java

(limited to 'bkucommon/src/main/java/at')

diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java
index 19fec084..eb708739 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java
@@ -1,153 +1,152 @@
-/*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package at.gv.egiz.bku.accesscontroller;
-
-import java.io.InputStream;
-import java.util.Hashtable;
-import java.util.List;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.bku.accesscontrol.config.AccessControl;
-import at.gv.egiz.bku.accesscontrol.config.Chain;
-import at.gv.egiz.bku.accesscontrol.config.Command;
-import at.gv.egiz.bku.accesscontrol.config.ObjectFactory;
-import at.gv.egiz.bku.accesscontrol.config.Param;
-import at.gv.egiz.bku.accesscontrol.config.Rule;
-import at.gv.egiz.bku.accesscontroller.RuleChecker.PEER_TYPE;
-import at.gv.egiz.bku.slexceptions.SLRuntimeException;
-
-public class AccessControllerFactory {
-
-	private static AccessControllerFactory instance = new AccessControllerFactory();
-	private static Log log = LogFactory.getLog(AccessControllerFactory.class);
-	private static JAXBContext jaxbContext;
-	public static String INPUT_CHAIN = "InputChain";
-	public static String OUTPUT_CHAIN = "OutputChain";
-
-	static {
-		try {
-			jaxbContext = JAXBContext.newInstance(ObjectFactory.class.getPackage()
-					.getName());
-		} catch (JAXBException e) {
-			log.fatal("Cannot init jaxbContext", e);
-		}
-	}
-
-	private Hashtable<String, ChainChecker> chainTable = new Hashtable<String, ChainChecker>();
-
-	private AccessControllerFactory() {
-	}
-
-	public static AccessControllerFactory getInstance() {
-		return instance;
-	}
-
-	/**
-	 * 
-	 * @param id
-	 * @return null if there is no chain with this id.
-	 */
-	public ChainChecker getChainChecker(String id) {
-		return chainTable.get(id);
-	}
-
-	public ChainChecker createChainChecker(String id, boolean register) {
-		ChainChecker cc = new ChainChecker(id);
-		if (register) {
-			chainTable.put(id, cc);
-		}
-		return cc;
-	}
-
-	public void registerChainChecker(ChainChecker cc) {
-		chainTable.put(cc.getId(), cc);
-	}
-
-	public CommandParamChecker createParamChecker(String cmd) {
-		if ((cmd != null) && (cmd.startsWith("Infobox"))) {
-			return new InfoboxParamChecker();
-		} else {
-			return null;
-		}
-	}
-
-	public RuleChecker createRuleChecker(Rule rule) {
-		RuleChecker rc;
-		rc = new RuleChecker(rule.getId());
-		Command cmd = rule.getCommand();
-		if (cmd != null) {
-			rc.setCommandName(cmd.getName());
-			for (Param p : cmd.getParam()) {
-				rc.addParameter(p.getName(), p.getValue());
-			}
-		}
-		rc.setAuthenticationClass(rule.getAuthClass());
-		if (rule.getIPv4Address() != null) {
-			rc.setPeerId(rule.getIPv4Address(), PEER_TYPE.IP);
-		} else if (rule.getDomainName() != null) {
-			rc.setPeerId(rule.getDomainName(), PEER_TYPE.HOST);
-		} else if (rule.getURL() != null) {
-			rc.setPeerId(rule.getURL(), PEER_TYPE.URL);
-		}
-		rc.setAction(rule.getAction().getRuleAction());
-		rc.setChainId(rule.getAction().getChainRef());
-		rc.setUserAction(rule.getUserInteraction());
-		return rc;
-	}
-
-	public void init(InputStream is) throws JAXBException {
-		chainTable.clear();
-		Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
-		AccessControl ac = (AccessControl) unmarshaller.unmarshal(is);
-		List<Chain> chainList = ac.getChains().getChain();
-		log.debug("Found " + chainList.size() + " chains in config");
-		for (Chain chain : chainList) {
-			log.trace("Creating chain: " + chain.getId());
-			ChainChecker cc = createChainChecker(chain.getId(), false);
-			List<Rule> ruleList = chain.getRules().getRule();
-			log
-					.debug("Found " + ruleList.size() + " rules in chain "
-							+ chain.getId());
-			for (Rule rule : ruleList) {
-				log.trace("Creating rule: " + rule.getId());
-				cc.addRule(createRuleChecker(rule));
-			}
-			registerChainChecker(cc);
-		}
-		validate();
-	}
-	
-	private void validate() {
-		for (ChainChecker chain : chainTable.values()) {
-			for (RuleChecker rule : chain.getRules()) {
-				if (rule.getChainId() != null) {
-					log.trace("Checking reference to chain: "+rule.getChainId());
-					if (getChainChecker(rule.getChainId()) == null) {
-						throw new SLRuntimeException("Invalid reference to unknown chain: "+rule.getChainId());
-					}
-				}
-			}
-		}
-	}
-
-}
+/*
+* Copyright 2008 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package at.gv.egiz.bku.accesscontroller;
+
+import java.io.InputStream;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.bku.accesscontrol.config.AccessControl;
+import at.gv.egiz.bku.accesscontrol.config.Chain;
+import at.gv.egiz.bku.accesscontrol.config.Command;
+import at.gv.egiz.bku.accesscontrol.config.ObjectFactory;
+import at.gv.egiz.bku.accesscontrol.config.Param;
+import at.gv.egiz.bku.accesscontrol.config.Rule;
+import at.gv.egiz.bku.accesscontroller.RuleChecker.PEER_TYPE;
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+
+public class AccessControllerFactory {
+
+	private static AccessControllerFactory instance = new AccessControllerFactory();
+    private static JAXBContext jaxbContext;
+	private final Logger log = LoggerFactory.getLogger(AccessControllerFactory.class);
+	public static String INPUT_CHAIN = "InputChain";
+	public static String OUTPUT_CHAIN = "OutputChain";
+
+	static {
+		try {
+			jaxbContext = JAXBContext.newInstance(ObjectFactory.class.getPackage()
+					.getName());
+		} catch (JAXBException e) {
+		    Logger log = LoggerFactory.getLogger(AccessControllerFactory.class);
+			log.error("Cannot init jaxbContext.", e);
+		}
+	}
+
+	private Hashtable<String, ChainChecker> chainTable = new Hashtable<String, ChainChecker>();
+
+	private AccessControllerFactory() {
+	}
+
+	public static AccessControllerFactory getInstance() {
+		return instance;
+	}
+
+	/**
+	 * 
+	 * @param id
+	 * @return null if there is no chain with this id.
+	 */
+	public ChainChecker getChainChecker(String id) {
+		return chainTable.get(id);
+	}
+
+	public ChainChecker createChainChecker(String id, boolean register) {
+		ChainChecker cc = new ChainChecker(id);
+		if (register) {
+			chainTable.put(id, cc);
+		}
+		return cc;
+	}
+
+	public void registerChainChecker(ChainChecker cc) {
+		chainTable.put(cc.getId(), cc);
+	}
+
+	public CommandParamChecker createParamChecker(String cmd) {
+		if ((cmd != null) && (cmd.startsWith("Infobox"))) {
+			return new InfoboxParamChecker();
+		} else {
+			return null;
+		}
+	}
+
+	public RuleChecker createRuleChecker(Rule rule) {
+		RuleChecker rc;
+		rc = new RuleChecker(rule.getId());
+		Command cmd = rule.getCommand();
+		if (cmd != null) {
+			rc.setCommandName(cmd.getName());
+			for (Param p : cmd.getParam()) {
+				rc.addParameter(p.getName(), p.getValue());
+			}
+		}
+		rc.setAuthenticationClass(rule.getAuthClass());
+		if (rule.getIPv4Address() != null) {
+			rc.setPeerId(rule.getIPv4Address(), PEER_TYPE.IP);
+		} else if (rule.getDomainName() != null) {
+			rc.setPeerId(rule.getDomainName(), PEER_TYPE.HOST);
+		} else if (rule.getURL() != null) {
+			rc.setPeerId(rule.getURL(), PEER_TYPE.URL);
+		}
+		rc.setAction(rule.getAction().getRuleAction());
+		rc.setChainId(rule.getAction().getChainRef());
+		rc.setUserAction(rule.getUserInteraction());
+		return rc;
+	}
+
+	public void init(InputStream is) throws JAXBException {
+		chainTable.clear();
+		Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+		AccessControl ac = (AccessControl) unmarshaller.unmarshal(is);
+		List<Chain> chainList = ac.getChains().getChain();
+		log.debug("Found {} chains in config.", chainList.size());
+		for (Chain chain : chainList) {
+			log.trace("Creating chain: {}.", chain.getId());
+			ChainChecker cc = createChainChecker(chain.getId(), false);
+			List<Rule> ruleList = chain.getRules().getRule();
+			log.debug("Found {} rules in chain {}.", ruleList.size(), chain.getId());
+			for (Rule rule : ruleList) {
+				log.trace("Creating rule: {}.", rule.getId());
+				cc.addRule(createRuleChecker(rule));
+			}
+			registerChainChecker(cc);
+		}
+		validate();
+	}
+	
+	private void validate() {
+		for (ChainChecker chain : chainTable.values()) {
+			for (RuleChecker rule : chain.getRules()) {
+				if (rule.getChainId() != null) {
+					log.trace("Checking reference to chain: {}.", rule.getChainId());
+					if (getChainChecker(rule.getChainId()) == null) {
+						throw new SLRuntimeException("Invalid reference to unknown chain: "+rule.getChainId());
+					}
+				}
+			}
+		}
+	}
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java
index 61d3d7a5..204513e0 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java
@@ -1,110 +1,110 @@
-/*
- * Copyright 2008 Federal Chancellery Austria and
- * Graz University of Technology
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package at.gv.egiz.bku.accesscontroller;
-
-import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.ANONYMOUS;
-import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.CERTIFIED;
-import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.CERTIFIED_GOV_AGENCY;
-import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.PSEUDO_ANONYMOUS;
-
-import java.net.URL;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-public class AuthenticationClassifier {
-	private static AuthenticationClassifier instance = new AuthenticationClassifier();
-	private static Log log = LogFactory.getLog(AuthenticationClassifier.class);
-	private final static String GOV_DOMAIN = ".gv.at";
-
-	private AuthenticationClassifier() {
-	}
-
-	public static boolean isGovAgency(X509Certificate cert) {
-		String[] rdns = (cert.getSubjectX500Principal().getName()).split(",");
-		for (String rdn : rdns) {
-			if (rdn.startsWith("CN=")) {
-				String dns = rdn.split("=")[1];
-				log.trace("Analyzing cn dn: " + dns);
-				if (dns.endsWith(GOV_DOMAIN)) {
-					return true;
-				}
-			}
-		}
-		try {
-			Collection<List<?>> sanList = cert.getSubjectAlternativeNames();
-			if (sanList != null) {
-				for (List<?> san : sanList) {
-					log.trace("Analyzing subj. alt name: " + san);
-					if ((Integer) san.get(0) == 2) {
-						String dns = (String) san.get(1);
-						if (dns.endsWith(GOV_DOMAIN)) {
-							return true;
-						}
-					}
-				}
-			}
-		} catch (CertificateParsingException e) {
-			log.error(e);
-		}
-		if ((cert.getExtensionValue("1.2.40.0.10.1.1.1") != null)
-        || (cert.getExtensionValue("1.2.40.0.10.1.1.2") != null)) {
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Client Certificates are currently not supported
-	 * 
-	 */
-	protected AuthenticationClass getMyAuthenticationClass(boolean isDataUrl,
-			URL url, X509Certificate cert) {
-		if (isDataUrl) {
-			if (url.getProtocol().equalsIgnoreCase("https")) {
-				if (isGovAgency(cert)) {
-					return CERTIFIED_GOV_AGENCY;
-				}
-				if (cert.getExtensionValue("1.2.40.0.10.1.1.1") != null) {
-					return CERTIFIED_GOV_AGENCY;
-				}
-				return CERTIFIED;
-			} else {
-				return PSEUDO_ANONYMOUS;
-			}
-		} else {
-			return ANONYMOUS;
-		}
-	}
-
-	/**
-	 * 
-	 * @param isDataUrl
-	 * @param url
-	 *          if the url's protocol is https a cert parameter must be provided.
-	 * @param cert
-	 * @return
-	 */
-	public static AuthenticationClass getAuthenticationClass(boolean isDataUrl,
-			URL url, X509Certificate cert) {
-		return instance.getMyAuthenticationClass(isDataUrl, url, cert);
-	}
-}
+/*
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.gv.egiz.bku.accesscontroller;
+
+import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.ANONYMOUS;
+import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.CERTIFIED;
+import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.CERTIFIED_GOV_AGENCY;
+import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.PSEUDO_ANONYMOUS;
+
+import java.net.URL;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AuthenticationClassifier {
+	private static AuthenticationClassifier instance = new AuthenticationClassifier();
+	private final static String GOV_DOMAIN = ".gv.at";
+
+	private AuthenticationClassifier() {
+	}
+
+	public static boolean isGovAgency(X509Certificate cert) {
+	    Logger log = LoggerFactory.getLogger(AuthenticationClassifier.class);
+		String[] rdns = (cert.getSubjectX500Principal().getName()).split(",");
+		for (String rdn : rdns) {
+			if (rdn.startsWith("CN=")) {
+				String dns = rdn.split("=")[1];
+				log.trace("Analyzing cn dn: " + dns);
+				if (dns.endsWith(GOV_DOMAIN)) {
+					return true;
+				}
+			}
+		}
+		try {
+			Collection<List<?>> sanList = cert.getSubjectAlternativeNames();
+			if (sanList != null) {
+				for (List<?> san : sanList) {
+					log.trace("Analyzing subj. alt name: " + san);
+					if ((Integer) san.get(0) == 2) {
+						String dns = (String) san.get(1);
+						if (dns.endsWith(GOV_DOMAIN)) {
+							return true;
+						}
+					}
+				}
+			}
+		} catch (CertificateParsingException e) {
+			log.error("Failed to parse certificate.", e);
+		}
+		if ((cert.getExtensionValue("1.2.40.0.10.1.1.1") != null)
+        || (cert.getExtensionValue("1.2.40.0.10.1.1.2") != null)) {
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Client Certificates are currently not supported
+	 * 
+	 */
+	protected AuthenticationClass getMyAuthenticationClass(boolean isDataUrl,
+			URL url, X509Certificate cert) {
+		if (isDataUrl) {
+			if (url.getProtocol().equalsIgnoreCase("https")) {
+				if (isGovAgency(cert)) {
+					return CERTIFIED_GOV_AGENCY;
+				}
+				if (cert.getExtensionValue("1.2.40.0.10.1.1.1") != null) {
+					return CERTIFIED_GOV_AGENCY;
+				}
+				return CERTIFIED;
+			} else {
+				return PSEUDO_ANONYMOUS;
+			}
+		} else {
+			return ANONYMOUS;
+		}
+	}
+
+	/**
+	 * 
+	 * @param isDataUrl
+	 * @param url
+	 *          if the url's protocol is https a cert parameter must be provided.
+	 * @param cert
+	 * @return
+	 */
+	public static AuthenticationClass getAuthenticationClass(boolean isDataUrl,
+			URL url, X509Certificate cert) {
+		return instance.getMyAuthenticationClass(isDataUrl, url, cert);
+	}
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java
index 716f81e4..6b24dcac 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java
@@ -1,91 +1,92 @@
-/*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package at.gv.egiz.bku.accesscontroller;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.bku.slexceptions.SLException;
-
-public class ChainChecker implements AccessChecker {
-	private static Log log = LogFactory.getLog(ChainChecker.class);
-	
-	private String id;
-	private List<RuleChecker> rules = new LinkedList<RuleChecker>();
-	
-	/**
-	 * 
-	 * @param id must not be null
-	 */
-	public ChainChecker(String id) {
-		if (id == null) {
-			throw new NullPointerException("Id argument must not be null");
-		}
-		this.id = id;
-	}
-	
-
-	public String getId() {
-		return id;
-	}
-
-	public void addRule(RuleChecker rule) {
-		if (rule != null) {
-			rules.add(rule);
-		}
-	}
-	
-	public List<RuleChecker> getRules() {
-		return Collections.unmodifiableList(rules);
-	}
-
-	@Override
-	public ChainResult check(AccessCheckerContext checkCtx) throws SLException {
-		log.debug("Processing chain: "+id);
-		for (RuleChecker rule : rules) {
-			log.trace("Checking rule: "+rule.getId());
-			RuleResult result = rule.check(checkCtx);
-			if (result.matchFound()) {
-				if (result.getDelegateChainId() != null) {
-					// process chain
-					ChainChecker cc = AccessControllerFactory.getInstance().getChainChecker(result.getDelegateChainId());
-					if (cc == null) {
-						log.error("Cannot delegate to chain. Unknown chain id: "+result.getDelegateChainId());
-						throw new SLException(4000);
-					}
-					ChainResult cr = cc.check(checkCtx);
-					if (cr.matchFound()) {
-						return cr;
-					}
-					// if chain does not contain matching rule
-					// cont. here.		
-					} else {
-						return result;
-					}
-			}
-		}
-		log.debug("Did not find a matching rule here");
-		return new ChainResult(null, null, false);
-	}
-
-	
-	
-}
+/*
+* Copyright 2008 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package at.gv.egiz.bku.accesscontroller;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.bku.slexceptions.SLException;
+
+public class ChainChecker implements AccessChecker {
+	
+    private final Logger log = LoggerFactory.getLogger(ChainChecker.class);
+	
+	private String id;
+	private List<RuleChecker> rules = new LinkedList<RuleChecker>();
+	
+	/**
+	 * 
+	 * @param id must not be null
+	 */
+	public ChainChecker(String id) {
+		if (id == null) {
+			throw new NullPointerException("Id argument must not be null");
+		}
+		this.id = id;
+	}
+	
+
+	public String getId() {
+		return id;
+	}
+
+	public void addRule(RuleChecker rule) {
+		if (rule != null) {
+			rules.add(rule);
+		}
+	}
+	
+	public List<RuleChecker> getRules() {
+		return Collections.unmodifiableList(rules);
+	}
+
+	@Override
+	public ChainResult check(AccessCheckerContext checkCtx) throws SLException {
+		log.debug("Processing chain: {}.", id);
+		for (RuleChecker rule : rules) {
+			log.trace("Checking rule: {}.", rule.getId());
+			RuleResult result = rule.check(checkCtx);
+			if (result.matchFound()) {
+				if (result.getDelegateChainId() != null) {
+					// process chain
+					ChainChecker cc = AccessControllerFactory.getInstance().getChainChecker(result.getDelegateChainId());
+					if (cc == null) {
+						log.error("Cannot delegate to chain. Unknown chain id: {}.", result.getDelegateChainId());
+						throw new SLException(4000);
+					}
+					ChainResult cr = cc.check(checkCtx);
+					if (cr.matchFound()) {
+						return cr;
+					}
+					// if chain does not contain matching rule
+					// cont. here.		
+					} else {
+						return result;
+					}
+			}
+		}
+		log.debug("Did not find a matching rule here.");
+		return new ChainResult(null, null, false);
+	}
+
+	
+	
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java
index 8fa328de..e7535e81 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java
@@ -1,74 +1,75 @@
-/*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package at.gv.egiz.bku.accesscontroller;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.bku.slcommands.InfoboxReadCommand;
-import at.gv.egiz.bku.slcommands.SLCommand;
-import at.gv.egiz.bku.slexceptions.SLRuntimeException;
-
-public class InfoboxParamChecker extends CommandParamChecker {
-	private static Log log = LogFactory.getLog(InfoboxParamChecker.class);
-
-	public final static String INFOBOX_ID = "InfoboxIdentifier";
-	public final static String PERSON_ID = "PersonIdentifier";
-	public final static String DERIVED = "derived";
-
-	@Override
-	public boolean checkParameter(SLCommand cmd) {
-		if (paramList.size() == 0) {
-			return true;
-		}
-
-		if (cmd instanceof InfoboxReadCommand) {
-			InfoboxReadCommand irc = (InfoboxReadCommand) cmd;
-			for (Tupel<String, String> param : paramList) {
-				if (param.getKey().equals(INFOBOX_ID)) {
-					if (!param.getVal().equals(irc.getInfoboxIdentifier())) {
-						return false;
-					}
-				} else if (param.getKey().equals(PERSON_ID)) {
-					if (param.getVal().equals(DERIVED)) {
-						if (irc.getIdentityLinkDomainId() == null) {
-							return false;
-						}
-					} else {
-						Pattern p = Pattern.compile(param.getVal());
-						Matcher m = p.matcher(irc.getIdentityLinkDomainId());
-						if (!m.matches()) {
-							return false;
-						}
-					}
-
-				} else {
-					throw new SLRuntimeException("Cannot handle parameter "
-							+ param.getKey());
-				}
-			}
-			return true;
-		} else {
-			log.error("Cannot handle parameter for command: " + cmd.getName());
-			throw new SLRuntimeException("Cannot handle parameters for command: "
-					+ cmd.getName());
-		}
-	}
-}
+/*
+* Copyright 2008 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package at.gv.egiz.bku.accesscontroller;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.bku.slcommands.InfoboxReadCommand;
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+
+public class InfoboxParamChecker extends CommandParamChecker {
+	
+    private final Logger log = LoggerFactory.getLogger(InfoboxParamChecker.class);
+
+	public final static String INFOBOX_ID = "InfoboxIdentifier";
+	public final static String PERSON_ID = "PersonIdentifier";
+	public final static String DERIVED = "derived";
+
+	@Override
+	public boolean checkParameter(SLCommand cmd) {
+		if (paramList.size() == 0) {
+			return true;
+		}
+
+		if (cmd instanceof InfoboxReadCommand) {
+			InfoboxReadCommand irc = (InfoboxReadCommand) cmd;
+			for (Tupel<String, String> param : paramList) {
+				if (param.getKey().equals(INFOBOX_ID)) {
+					if (!param.getVal().equals(irc.getInfoboxIdentifier())) {
+						return false;
+					}
+				} else if (param.getKey().equals(PERSON_ID)) {
+					if (param.getVal().equals(DERIVED)) {
+						if (irc.getIdentityLinkDomainId() == null) {
+							return false;
+						}
+					} else {
+						Pattern p = Pattern.compile(param.getVal());
+						Matcher m = p.matcher(irc.getIdentityLinkDomainId());
+						if (!m.matches()) {
+							return false;
+						}
+					}
+
+				} else {
+					throw new SLRuntimeException("Cannot handle parameter "
+							+ param.getKey());
+				}
+			}
+			return true;
+		} else {
+			log.error("Cannot handle parameter for command: {}.", cmd.getName());
+			throw new SLRuntimeException("Cannot handle parameters for command: "
+					+ cmd.getName());
+		}
+	}
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java
index 1cba89ef..33283eda 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java
@@ -1,203 +1,203 @@
-/*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package at.gv.egiz.bku.accesscontroller;
-
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.bku.slcommands.SLCommand;
-import at.gv.egiz.bku.slexceptions.SLRuntimeException;
-
-public class RuleChecker implements AccessChecker {
-
-	private static Log log = LogFactory.getLog(RuleChecker.class);
-
-	public static enum PEER_TYPE {
-		HOST, IP, URL
-	};
-
-	protected String id;
-	protected AuthenticationClass authenticationClass;
-	protected String commandName;
-	protected Pattern commandNamePattern;
-	protected String peerId;
-	protected Pattern peerIdPattern;
-	protected PEER_TYPE peerType;
-	protected Action action;
-	protected UserAction userAction;
-	protected String chainId;
-	protected CommandParamChecker paramChecker;
-
-	public RuleChecker(String id) {
-		if (id == null) {
-			throw new NullPointerException("Id argument must not be null");
-		}
-		this.id = id;
-	}
-
-	public void setAuthenticationClass(String ac) {
-		if (ac != null) {
-			AuthenticationClass tmp = AuthenticationClass.fromString(ac);
-			if (tmp == null) {
-				throw new SLRuntimeException("Unknown authentication class " + ac);
-			}
-			authenticationClass = tmp;
-		}
-	}
-
-	public void setAction(String ac) {
-		if (ac != null) {
-			Action tmp = Action.fromString(ac);
-			if (tmp == null) {
-				throw new SLRuntimeException("Unknown action " + ac);
-			}
-			action = tmp;
-		}
-	}
-
-	public void setUserAction(String uac) {
-		if (uac != null) {
-			UserAction tmp = UserAction.fromString(uac);
-			if (tmp == null) {
-				throw new SLRuntimeException("Unknown user action " + uac);
-			}
-			userAction = tmp;
-		}
-	}
-
-	public void setChainId(String chainId) {
-		this.chainId = chainId;
-	}
-
-	public void setPeerId(String peerId, PEER_TYPE type) {
-		this.peerType = type;
-		this.peerId = peerId;
-		peerIdPattern = Pattern.compile(peerId);
-	}
-
-	public void setCommandName(String commandName) {
-		this.commandName = commandName;
-		commandNamePattern = Pattern.compile(commandName);
-		paramChecker = AccessControllerFactory.getInstance().createParamChecker(
-				commandName);
-	}
-
-	/**
-	 * Make sure to set the commandName first
-	 * 
-	 * @param key
-	 * @param value
-	 */
-	public void addParameter(String key, String value) {
-		if (paramChecker == null) {
-			throw new IllegalArgumentException("Cannot set parameters for command "
-					+ commandName);
-		}
-		paramChecker.addParameter(key, value);
-	}
-
-	public String getId() {
-		return id;
-	}
-
-	protected boolean matchAuthenticationClass(AuthenticationClass cls) {
-		if ((this.authenticationClass == null) || (cls == null)) {
-			return true;
-		}
-		return this.authenticationClass.compareTo(cls) <= 0;
-	}
-
-	protected boolean matchCommandName(SLCommand cmd) {
-		if ((commandName == null) || (cmd == null)) {
-			return true;
-		}
-		Matcher matcher = commandNamePattern.matcher(cmd.getName());
-		if (matcher.matches()) {
-			if (paramChecker != null) {
-				return paramChecker.checkParameter(cmd);
-			} else {
-				return true;
-			}
-		} else {
-			return false;
-		}
-	}
-
-	protected boolean matchPeerId(String peerUrl) {
-		if ((peerId == null) || (peerUrl == null)) {
-			return true;
-		}
-		if (peerType == PEER_TYPE.URL) {
-			Matcher matcher = peerIdPattern.matcher(peerUrl);
-			return matcher.matches();
-		} else {
-			try {
-				URL url = new URL(peerUrl);
-				if (peerType == PEER_TYPE.HOST) {
-					try {
-						String host = url.getHost();
-						String hostName = InetAddress.getByName(host)
-								.getCanonicalHostName();
-						Matcher matcher = peerIdPattern.matcher(hostName);
-						return matcher.matches();
-					} catch (UnknownHostException e) {
-						log.error("Cannot resolve hostname", e);
-						return false;
-					}
-				} else {
-					try {
-						String hostAddr = InetAddress.getByName(url.getHost())
-								.getHostAddress();
-						Matcher matcher = peerIdPattern.matcher(hostAddr);
-						return matcher.matches();
-					} catch (UnknownHostException e) {
-						log.error("Cannot resolve host address", e);
-						return false;
-					}
-				}
-			} catch (MalformedURLException e) {
-				log.error("Cannot parse url", e);
-				return false;
-			}
-		}
-	}
-
-	@Override
-	public RuleResult check(AccessCheckerContext checkCtx) {
-		log.debug("Processing rule: " + id);
-		if (matchAuthenticationClass(checkCtx.getAuthenticationClass())
-				&& matchCommandName(checkCtx.getCommand())
-				&& matchPeerId(checkCtx.getPeerUrl())) {
-			log.debug("Match found for rule: " + id);
-			return new RuleResult(action, userAction, true, chainId);
-		}
-		log.debug("No match found for rule: " + id);
-		return new RuleResult(action, userAction, false, chainId);
-	}
-
-	public String getChainId() {
-		return chainId;
-	}
-
-}
+/*
+* Copyright 2008 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package at.gv.egiz.bku.accesscontroller;
+
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+
+public class RuleChecker implements AccessChecker {
+
+	private final Logger log = LoggerFactory.getLogger(RuleChecker.class);
+
+	public static enum PEER_TYPE {
+		HOST, IP, URL
+	};
+
+	protected String id;
+	protected AuthenticationClass authenticationClass;
+	protected String commandName;
+	protected Pattern commandNamePattern;
+	protected String peerId;
+	protected Pattern peerIdPattern;
+	protected PEER_TYPE peerType;
+	protected Action action;
+	protected UserAction userAction;
+	protected String chainId;
+	protected CommandParamChecker paramChecker;
+
+	public RuleChecker(String id) {
+		if (id == null) {
+			throw new NullPointerException("Id argument must not be null");
+		}
+		this.id = id;
+	}
+
+	public void setAuthenticationClass(String ac) {
+		if (ac != null) {
+			AuthenticationClass tmp = AuthenticationClass.fromString(ac);
+			if (tmp == null) {
+				throw new SLRuntimeException("Unknown authentication class " + ac);
+			}
+			authenticationClass = tmp;
+		}
+	}
+
+	public void setAction(String ac) {
+		if (ac != null) {
+			Action tmp = Action.fromString(ac);
+			if (tmp == null) {
+				throw new SLRuntimeException("Unknown action " + ac);
+			}
+			action = tmp;
+		}
+	}
+
+	public void setUserAction(String uac) {
+		if (uac != null) {
+			UserAction tmp = UserAction.fromString(uac);
+			if (tmp == null) {
+				throw new SLRuntimeException("Unknown user action " + uac);
+			}
+			userAction = tmp;
+		}
+	}
+
+	public void setChainId(String chainId) {
+		this.chainId = chainId;
+	}
+
+	public void setPeerId(String peerId, PEER_TYPE type) {
+		this.peerType = type;
+		this.peerId = peerId;
+		peerIdPattern = Pattern.compile(peerId);
+	}
+
+	public void setCommandName(String commandName) {
+		this.commandName = commandName;
+		commandNamePattern = Pattern.compile(commandName);
+		paramChecker = AccessControllerFactory.getInstance().createParamChecker(
+				commandName);
+	}
+
+	/**
+	 * Make sure to set the commandName first
+	 * 
+	 * @param key
+	 * @param value
+	 */
+	public void addParameter(String key, String value) {
+		if (paramChecker == null) {
+			throw new IllegalArgumentException("Cannot set parameters for command "
+					+ commandName);
+		}
+		paramChecker.addParameter(key, value);
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	protected boolean matchAuthenticationClass(AuthenticationClass cls) {
+		if ((this.authenticationClass == null) || (cls == null)) {
+			return true;
+		}
+		return this.authenticationClass.compareTo(cls) <= 0;
+	}
+
+	protected boolean matchCommandName(SLCommand cmd) {
+		if ((commandName == null) || (cmd == null)) {
+			return true;
+		}
+		Matcher matcher = commandNamePattern.matcher(cmd.getName());
+		if (matcher.matches()) {
+			if (paramChecker != null) {
+				return paramChecker.checkParameter(cmd);
+			} else {
+				return true;
+			}
+		} else {
+			return false;
+		}
+	}
+
+	protected boolean matchPeerId(String peerUrl) {
+		if ((peerId == null) || (peerUrl == null)) {
+			return true;
+		}
+		if (peerType == PEER_TYPE.URL) {
+			Matcher matcher = peerIdPattern.matcher(peerUrl);
+			return matcher.matches();
+		} else {
+			try {
+				URL url = new URL(peerUrl);
+				if (peerType == PEER_TYPE.HOST) {
+					try {
+						String host = url.getHost();
+						String hostName = InetAddress.getByName(host)
+								.getCanonicalHostName();
+						Matcher matcher = peerIdPattern.matcher(hostName);
+						return matcher.matches();
+					} catch (UnknownHostException e) {
+						log.error("Cannot resolve hostname.", e);
+						return false;
+					}
+				} else {
+					try {
+						String hostAddr = InetAddress.getByName(url.getHost())
+								.getHostAddress();
+						Matcher matcher = peerIdPattern.matcher(hostAddr);
+						return matcher.matches();
+					} catch (UnknownHostException e) {
+						log.error("Cannot resolve host address.", e);
+						return false;
+					}
+				}
+			} catch (MalformedURLException e) {
+				log.error("Cannot parse url.", e);
+				return false;
+			}
+		}
+	}
+
+	@Override
+	public RuleResult check(AccessCheckerContext checkCtx) {
+		log.debug("Processing rule: {}.", id);
+		if (matchAuthenticationClass(checkCtx.getAuthenticationClass())
+				&& matchCommandName(checkCtx.getCommand())
+				&& matchPeerId(checkCtx.getPeerUrl())) {
+			log.debug("Match found for rule: {}.", id);
+			return new RuleResult(action, userAction, true, chainId);
+		}
+		log.debug("No match found for rule: {}", id);
+		return new RuleResult(action, userAction, false, chainId);
+	}
+
+	public String getChainId() {
+		return chainId;
+	}
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java
index 482d3ecb..0596f0d0 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java
@@ -1,118 +1,119 @@
-/*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package at.gv.egiz.bku.accesscontroller;
-
-import java.io.InputStream;
-
-import javax.xml.bind.JAXBException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.bku.slcommands.SLCommand;
-import at.gv.egiz.bku.slcommands.SLSourceContext;
-import at.gv.egiz.bku.slcommands.SLTargetContext;
-
-/**
- * Facade for the access controller
- */
-public class SecurityManagerFacade {
-
-	private static Log log = LogFactory.getLog(SecurityManagerFacade.class);
-
-	private boolean allowUnmatched = false;
-	private ChainChecker inputFilter = null;
-	private ChainChecker outputFilter = null;
-	
-	public boolean mayInvokeCommand(SLCommand cmd, SLSourceContext ctx) {
-		if (inputFilter != null) {
-			AuthenticationClass ac = AuthenticationClassifier.getAuthenticationClass(
-					ctx.isSourceIsDataURL(), ctx.getSourceUrl(), ctx
-							.getSourceCertificate());
-			AccessCheckerContext acc = new AccessCheckerContext(cmd, ac, ctx
-					.getSourceUrl().toString());
-			try {
-				ChainResult cr = inputFilter.check(acc);
-				if (cr.matchFound()) {
-					if (cr.getAction() == Action.ALLOW) {
-						return true;
-					} else {
-						return false;
-					}
-				} else {
-					return allowUnmatched;
-				}
-			} catch (Exception e) {
-				log.error(e);
-				return false;
-			}
-		} else {
-			log.warn("No input chain defined");
-			return allowUnmatched;
-		}
-	}
-
-	public boolean maySendResult(SLCommand cmd, SLTargetContext ctx) {
-		if (outputFilter != null) {
-			AuthenticationClass ac = AuthenticationClassifier.getAuthenticationClass(
-					ctx.isTargetIsDataURL(), ctx.getTargetUrl(), ctx
-							.getTargetCertificate());
-			AccessCheckerContext acc = new AccessCheckerContext(cmd, ac, ctx
-					.getTargetUrl().toString());
-			try {
-				ChainResult cr = outputFilter.check(acc);
-				if (cr.matchFound()) {
-					if (cr.getAction() == Action.ALLOW) {
-						return true;
-					} else {
-						return false;
-					}
-				} else {
-					return allowUnmatched;
-				}
-			} catch (Exception e) {
-				log.error(e);
-				return false;
-			}
-		} else {
-			log.warn("No output chain defined");
-			return allowUnmatched;
-		}
-	}
-
-	/**
-	 * Default policy if not match was found
-	 * 
-	 * @param allow
-	 */
-	public void setAllowUnmatched(boolean allow) {
-		this.allowUnmatched = allow;
-	}
-
-	public void init(InputStream is) {
-		inputFilter = null;
-		outputFilter = null;
-		AccessControllerFactory fab = AccessControllerFactory.getInstance();
-		try {
-			fab.init(is);
-		} catch (JAXBException e) {
-			log.error(e);
-		}
-		inputFilter = fab.getChainChecker(AccessControllerFactory.INPUT_CHAIN);
-		outputFilter = fab.getChainChecker(AccessControllerFactory.OUTPUT_CHAIN);
-	}
-}
+/*
+* Copyright 2008 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package at.gv.egiz.bku.accesscontroller;
+
+import java.io.InputStream;
+
+import javax.xml.bind.JAXBException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slcommands.SLSourceContext;
+import at.gv.egiz.bku.slcommands.SLTargetContext;
+import at.gv.egiz.bku.slexceptions.SLException;
+
+/**
+ * Facade for the access controller
+ */
+public class SecurityManagerFacade {
+
+	private final Logger log = LoggerFactory.getLogger(SecurityManagerFacade.class);
+
+	private boolean allowUnmatched = false;
+	private ChainChecker inputFilter = null;
+	private ChainChecker outputFilter = null;
+	
+	public boolean mayInvokeCommand(SLCommand cmd, SLSourceContext ctx) {
+		if (inputFilter != null) {
+			AuthenticationClass ac = AuthenticationClassifier.getAuthenticationClass(
+					ctx.isSourceIsDataURL(), ctx.getSourceUrl(), ctx
+							.getSourceCertificate());
+			AccessCheckerContext acc = new AccessCheckerContext(cmd, ac, ctx
+					.getSourceUrl().toString());
+			try {
+				ChainResult cr = inputFilter.check(acc);
+				if (cr.matchFound()) {
+					if (cr.getAction() == Action.ALLOW) {
+						return true;
+					} else {
+						return false;
+					}
+				} else {
+					return allowUnmatched;
+				}
+			} catch (SLException e) {
+				log.error("Check failed.", e);
+				return false;
+			}
+		} else {
+			log.warn("No input chain defined.");
+			return allowUnmatched;
+		}
+	}
+
+	public boolean maySendResult(SLCommand cmd, SLTargetContext ctx) {
+		if (outputFilter != null) {
+			AuthenticationClass ac = AuthenticationClassifier.getAuthenticationClass(
+					ctx.isTargetIsDataURL(), ctx.getTargetUrl(), ctx
+							.getTargetCertificate());
+			AccessCheckerContext acc = new AccessCheckerContext(cmd, ac, ctx
+					.getTargetUrl().toString());
+			try {
+				ChainResult cr = outputFilter.check(acc);
+				if (cr.matchFound()) {
+					if (cr.getAction() == Action.ALLOW) {
+						return true;
+					} else {
+						return false;
+					}
+				} else {
+					return allowUnmatched;
+				}
+			} catch (SLException e) {
+				log.error("Check failed.", e);
+				return false;
+			}
+		} else {
+			log.warn("No output chain defined.");
+			return allowUnmatched;
+		}
+	}
+
+	/**
+	 * Default policy if not match was found
+	 * 
+	 * @param allow
+	 */
+	public void setAllowUnmatched(boolean allow) {
+		this.allowUnmatched = allow;
+	}
+
+	public void init(InputStream is) {
+		inputFilter = null;
+		outputFilter = null;
+		AccessControllerFactory fab = AccessControllerFactory.getInstance();
+		try {
+			fab.init(is);
+		} catch (JAXBException e) {
+			log.error("Failed to initialize AccessControllerFactory.", e);
+		}
+		inputFilter = fab.getChainChecker(AccessControllerFactory.INPUT_CHAIN);
+		outputFilter = fab.getChainChecker(AccessControllerFactory.OUTPUT_CHAIN);
+	}
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessor.java
index 23f62134..5201e817 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessor.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessor.java
@@ -16,74 +16,119 @@
 */
 package at.gv.egiz.bku.binding;
 
-import at.gv.egiz.bku.conf.Configuration;
-import java.io.InputStream;
 import java.util.Date;
+import java.util.Locale;
 
+import org.apache.commons.configuration.Configuration;
+import org.slf4j.MDC;
+
+import at.gv.egiz.bku.slcommands.SLCommandFactory;
 import at.gv.egiz.bku.slcommands.SLCommandInvoker;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
 import at.gv.egiz.stal.STAL;
 
 public abstract class AbstractBindingProcessor implements BindingProcessor {
+  
+  protected Configuration configuration;
+
+  protected SLCommandFactory slCommandFactory;
+
+  protected Locale locale = Locale.getDefault();
+
   protected Id id;
-  protected Configuration config;
   protected STAL stal;
   protected SLCommandInvoker commandInvoker;
+  
   protected long lastAccessedTime = System.currentTimeMillis();
 
-  public AbstractBindingProcessor(String idString) {
-    this.id = IdFactory.getInstance().createId(idString);
+  protected URLDereferencer urlDereferencer;
+
+  public void setConfiguration(Configuration configuration) {
+    this.configuration = configuration;
   }
 
-  /**
-   * @see java.lang.Thread#run()
-   */
-  public abstract void run();
+  @Override
+  public void setSlCommandFactory(SLCommandFactory slCommandFactory) {
+    this.slCommandFactory = slCommandFactory;
+  }
 
-  /**
-   * The caller is advised to check the result in case an error occurred.
-   * 
-   * @see #getResult()
-   */
-  public abstract void consumeRequestStream(InputStream aIs);
+  @Override
+  public void setLocale(Locale locale) {
+  	if (locale == null) {
+  		throw new NullPointerException("Locale must not be set to null.");
+  	}
+  	this.locale = locale;
+  }
+
+  @Override
+  public void init(String id, STAL stal, SLCommandInvoker commandInvoker) {
+    if (id == null) {
+      throw new NullPointerException("Id must not be null.");
+    }
+    if (stal == null) {
+      throw new NullPointerException("STAL must not null.");
+    }
+    if (commandInvoker == null) {
+      throw new NullPointerException("CommandInvoker must null.");
+    }
+    this.id = IdFactory.getInstance().createId(id);
+    this.stal = stal;
+    this.commandInvoker = commandInvoker;
+  }
 
+  @Override
   public Id getId() {
     return id;
   }
 
+  @Override
   public STAL getSTAL() {
     return stal;
   }
 
+  @Override
   public SLCommandInvoker getCommandInvoker() {
     return commandInvoker;
   }
-  
+
+  @Override
   public void updateLastAccessTime() {
     lastAccessedTime = System.currentTimeMillis();
   }
 
+  @Override
   public Date getLastAccessTime() {
     return new Date(lastAccessedTime);
   }
 
-  /**
-   * To be called after object creation.
-   * 
-   * @param aStal
-   *          must not be null
-   * @param aCommandInvoker
-   *          must not be null
-   */
-  public void init(STAL aStal, SLCommandInvoker aCommandInvoker, Configuration conf) {
-    if (aStal == null) {
-      throw new NullPointerException("STAL must not be set to null");
+  @Override
+  public void run() {
+    
+    if (this.id != null) {
+      MDC.put("id", this.id.toString());
     }
-    if (aCommandInvoker == null) {
-      throw new NullPointerException("Commandinvoker must not be set to null");
+    try {
+      process();
+    } finally {
+      MDC.remove("id");
     }
-    config = conf;
-    stal = aStal;
-    commandInvoker = aCommandInvoker;
-    Thread.currentThread().setName("BPID#"+getId().toString());
+    
+  }
+  
+  public abstract void process();
+
+  /**
+   * @return the urlDereferencer
+   */
+  public URLDereferencer getUrlDereferencer() {
+    return urlDereferencer;
+  }
+
+  /**
+   * @param urlDereferencer the urlDereferencer to set
+   */
+  public void setUrlDereferencer(URLDereferencer urlDereferencer) {
+    this.urlDereferencer = urlDereferencer;
   }
+  
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessorFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessorFactory.java
new file mode 100644
index 00000000..8cf71260
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessorFactory.java
@@ -0,0 +1,81 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.binding;
+
+import java.util.Set;
+
+import org.apache.commons.configuration.Configuration;
+
+import at.gv.egiz.bku.slcommands.SLCommandFactory;
+import at.gv.egiz.bku.utils.binding.Protocol;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
+
+
+public abstract class AbstractBindingProcessorFactory implements BindingProcessorFactory {
+
+  protected Set<Protocol> supportedProtocols;
+  protected SLCommandFactory slCommandFactory;
+  protected Configuration configuration;
+  protected URLDereferencer urlDereferencer;
+
+  @Override
+  public Set<Protocol> getSupportedProtocols() {
+    return supportedProtocols;
+  }
+
+  @Override
+  public SLCommandFactory getSlCommandFactory() {
+    return slCommandFactory;
+  }
+
+  @Override
+  public void setSlCommandFactory(SLCommandFactory slCommandFactory) {
+    this.slCommandFactory = slCommandFactory;    
+  }
+
+  @Override
+  public Configuration getConfiguration() {
+    return configuration;
+  }
+
+  @Override
+  public void setConfiguration(Configuration configuration) {
+    this.configuration = configuration;
+  }
+
+  /**
+   * @return the urlDereferencer
+   */
+  public URLDereferencer getUrlDereferencer() {
+    return urlDereferencer;
+  }
+
+  /**
+   * @param urlDereferencer the urlDereferencer to set
+   */
+  public void setUrlDereferencer(URLDereferencer urlDereferencer) {
+    this.urlDereferencer = urlDereferencer;
+  }
+
+  protected void configureBindingProcessor(AbstractBindingProcessor bindingProcessor) {
+    bindingProcessor.setConfiguration(configuration);
+    bindingProcessor.setSlCommandFactory(slCommandFactory);
+    bindingProcessor.setUrlDereferencer(urlDereferencer);
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java
index 0d978992..148fe296 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java
@@ -1,78 +1,147 @@
 /*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package at.gv.egiz.bku.binding;
 
-import at.gv.egiz.bku.conf.Configuration;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Date;
 import java.util.Locale;
 
+import at.gv.egiz.bku.slcommands.SLCommandFactory;
 import at.gv.egiz.bku.slcommands.SLCommandInvoker;
 import at.gv.egiz.stal.STAL;
 
 /**
- * Represents an single instance of a SL HTTP binding.
+ * BindingProcessors implement the processing of a specific protocol binding
+ * (e.g. HTTP) for Security Layer requests.
  * 
- * @author wbauer
- *
+ * @author wbauer, mcentner
  */
 public interface BindingProcessor extends Runnable {
 
   /**
-   * The stream must be read completely within this method.
+   * Sets the command factory for creating Security Layer. Must be set before
+   * {@link #consumeRequestStream(String, InputStream)} is called.
+   * 
+   * @param slCommandFactory
+   *          the command factory for creating Security Layer commands.
+   */
+  void setSlCommandFactory(SLCommandFactory slCommandFactory);
+
+  /**
+   * Sets the preferred locale for user interaction. If the locale is not set
+   * the default locale will be used. Should be set before
+   * {@link #consumeRequestStream(String, InputStream)} is called to allow for a
+   * proper localization.
+   * 
+   * @param locale
+   *          must not be null.
+   */
+  public void setLocale(Locale locale);
+
+  /**
+   * Instructs this BindingProcessor to consume the request
+   * <code>inputStream</code>.
+   * <p>
+   * Implementing classes are assumed to read the entire provided
+   * <code>inputStream</code>
+   * </p>
+   * <p>
+   * Any errors are reported via the result produced by this BindingProcessor.
+   * </p>
    * 
-   * The caller is advised to check the result in case an error occurred.
+   * @param url
+   *          the URL request is associated with (e.g. has been received on).
+   * 
+   * @see BindingProcessor#writeResultTo(OutputStream, String)
+   */
+  public void consumeRequestStream(String url, InputStream aIs);
+
+  /**
+   * Initialize this BindingProcessor for processing. This method must be called
+   * before {@link #run()} is called.
    * 
-   * @see #getResult()
+   * @param id
+   *          the (unique) processing id (usually a HTTP session id)
+   * @param stal
+   *          the STAL
+   * @param commandInvoker
+   *          the CommandInvoker
+   * @throws NullPointerException
+   *           if one of the provided parameters is <code>null</code>
    */
-  public void consumeRequestStream(InputStream aIs);
+  public void init(String id, STAL stal, SLCommandInvoker commandInvoker);
 
   /**
-   * The unique Id of this http binding instance.
-   * @return
+   * Returns the unique processing id.
+   * 
+   * @return the unique processing id or <code>null</code> if not yet assigned.
    */
   public Id getId();
 
   /**
-   * The used underlying STAL instance
-   * @return
+   * Returns the STAL used for processing.
+   * 
+   * @return the STAL used for processing or <code>null</code> if not yet
+   *         assigned.
    */
   public STAL getSTAL();
 
+  /**
+   * Returns the CommandInvoker used for processing.
+   * 
+   * @return the CommandInvoker used for processing or <code>null</code> if not
+   *         yet assigned.
+   */
   public SLCommandInvoker getCommandInvoker();
 
-  public Date getLastAccessTime();
-  
-  public void updateLastAccessTime();
-  
+  /**
+   * Returns the <code>ContentType</code> of the processing result.
+   * 
+   * @return the <code>ContentType</code> type of the processing result or
+   *         <code>null</code> if a result is not yet available.
+   */
   public String getResultContentType();
-  
-  public void writeResultTo(OutputStream os, String encoding) throws IOException;
 
-  public void init(STAL aStal, SLCommandInvoker aCommandInvoker, Configuration config);
-  
   /**
-  * Sets the preferred locale for userinteraction.
-  * If the locale is not set the default locale will be used.
-  * @param locale must not be null.
-  */
- public void setLocale(Locale locale);
- 
- public boolean isFinished();
+   * Writes the processing result to the given <code>outputStream</code> using
+   * the given character <code>encoding</code>.
+   * 
+   * @param outputStream
+   *          the OutputStream to write the result to
+   * @param encoding
+   *          the character encoding to be used
+   * @throws IOException
+   *           if writing to <code>outputStream</code> fails for any reason
+   */
+  public void writeResultTo(OutputStream outputStream, String encoding)
+      throws IOException;
+
+  /**
+   * Returns the time of the last access to this BindingProcessor instance.
+   * 
+   * @return the time of the last access to this BindingProcessor instance.
+   */
+  public Date getLastAccessTime();
+
+  /**
+   * Updates the time this BindingProcessor was accessed last.
+   */
+  public void updateLastAccessTime();
+
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFactory.java
new file mode 100644
index 00000000..ac922974
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFactory.java
@@ -0,0 +1,42 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.binding;
+
+import java.util.Set;
+
+import org.apache.commons.configuration.Configuration;
+
+import at.gv.egiz.bku.slcommands.SLCommandFactory;
+import at.gv.egiz.bku.utils.binding.Protocol;
+
+
+public interface BindingProcessorFactory {
+  
+  public Set<Protocol> getSupportedProtocols(); 
+  
+  public void setConfiguration(Configuration configuration);
+  
+  public Configuration getConfiguration();
+
+  public void setSlCommandFactory(SLCommandFactory commandFactory);
+  
+  public SLCommandFactory getSlCommandFactory();
+  
+  public BindingProcessor createBindingProcessor();
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFuture.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFuture.java
new file mode 100644
index 00000000..f0c65323
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFuture.java
@@ -0,0 +1,73 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.binding;
+
+import java.util.concurrent.FutureTask;
+
+public class BindingProcessorFuture extends FutureTask<Object> {
+
+  private BindingProcessor bindingProcessor;
+  
+  private long startTime;
+  
+  private long executionTime;
+  
+  public BindingProcessorFuture(BindingProcessor bindingProcessor) {
+    super(bindingProcessor, null);
+    this.bindingProcessor = bindingProcessor;
+  }
+
+  /**
+   * @return the bindingProcessor
+   */
+  public BindingProcessor getBindingProcessor() {
+    return bindingProcessor;
+  }
+
+  /* (non-Javadoc)
+   * @see java.util.concurrent.FutureTask#run()
+   */
+  @Override
+  public void run() {
+    startTime = System.currentTimeMillis();
+    try {
+      super.run();
+    } finally {
+      executionTime = System.currentTimeMillis() - startTime;
+    }
+  }
+
+  /**
+   * @return the startTime
+   */
+  public long getStartTime() {
+    return startTime;
+  }
+
+  /**
+   * @return the executionTime
+   */
+  public long getExecutionTime() {
+    return executionTime;
+  }
+  
+  public long getAge() {
+    return System.currentTimeMillis() - startTime;
+  }
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java
index 9cad95a4..f32d3c4b 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java
@@ -1,107 +1,103 @@
 /*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package at.gv.egiz.bku.binding;
 
-import java.net.MalformedURLException;
 import java.util.Locale;
 import java.util.Set;
 
-import at.gv.egiz.bku.slcommands.SLCommandInvoker;
-import at.gv.egiz.stal.STALFactory;
-
 /**
- * Central player that handles the protocol binding.
- * 
- * @author wbauer
+ * A <code>BindingProcessorManager</code> provides factory methods for creating
+ * <code>BindingProcessor</code>s and allows for scheduling them for processing.
  * 
+ * @author wbauer, mcentner
  */
 public interface BindingProcessorManager {
 
   /**
-   * FactoryMethod creating a new BindingProcessor object.
-   * The created binding processor must be passed to the process method to execute.
+   * Creates a new BindingProcessor for the given <code>protocol</code>.
    * 
-   * @param urlString
-   *          the source url
-   * @param aSessionId
-   *          optional an external sessionId (e.g. http session) could be
-   *          provided. This parameter may be null.
-   * @param locale the locale used for user interaction, may be null
+   * @param protocol
+   *          the name of the protocol binding the created BindingProcessor is
+   *          required to implement
+   * @param locale
+   *          the locale to be used by the binding processor, may be
+   *          <code>null</code>
    */
-  public BindingProcessor createBindingProcessor(String urlString,
-      String aSessionId, Locale locale) throws MalformedURLException;
+  public BindingProcessor createBindingProcessor(String protocol, Locale locale);
 
   /**
-   * FactoryMethod creating a new BindingProcessor object.
-   * The created binding processor must be passed to the process method to execute.
+   * Creates a new BindingProcessor for the given <code>protocol</code>.
    * 
-   * @param protcol
-   *          the source url
-   * @param aSessionId
-   *          optional an external sessionId (e.g. http session) could be
-   *          provided. This parameter may be null.
+   * @param protocol
+   *          the name of the protocol binding the created BindingProcessor is
+   *          required to implement
    */
-  public BindingProcessor createBindingProcessor(String urlString,
-      String aSessionId) throws MalformedURLException;
+  public BindingProcessor createBindingProcessor(String protocol);
 
-  
   /**
-   * Gets the binding processor with a certain id. The binding processor must be passed to the 
-   * process method before it is managed and thus returned by this method.
-   * @param aId must not be null
-   * @return null if the binding processor was not "processed" before.
+   * Returns the BindingProcessor which has been scheduled for processing with
+   * the given <code>id</code>.
+   * 
+   * @param id
+   *          the processing id of the requested BindingProcessor
+   * 
+   * @return the BindingProcessor which has been scheduled for processing with
+   *         the given <code>id</code>, or <code>null</code> if no
+   *         BindingProcessor has been scheduled with the given <code>id</code>.
    */
-  public BindingProcessor getBindingProcessor(Id aId);
+  public BindingProcessor getBindingProcessor(Id id);
 
   /**
-   * Sets the STAL factory that is used for creating STAL objects that are used by BindingProcessor objects.
-   * For each new BindingProcessor a new STAL object is created.
-   * @param aStalFactory the factory to be used. Must not be null.
+   * Schedules the given BindingProcessor for processing.
+   * <p>
+   * <ol>
+   * <li>Creates a processing context with the given <code>id</code>.</li>
+   * <li>Schedules the given BindingProcessor for processing, and</li>
+   * <li>Immediately returns the processing context.</li>
+   * </ol>
+   * </p>
+   * 
+   * @param id
+   * @param bindingProcessor
    */
-  public void setSTALFactory(STALFactory aStalFactory);
-  
+  public BindingProcessorFuture process(Id id, BindingProcessor bindingProcessor);
+
   /**
-   * Sets the invoker to be used.
-   * @param invoker
+   * Removes the BindingProcessor with the given processing id.
+   * 
+   * @param id
+   *          the processing id of the BindingProcessor to be removed
    */
-  public void setSLCommandInvoker(SLCommandInvoker invoker);
+  public void removeBindingProcessor(Id id);
 
   /**
-   * Creates a processing context,
-   * schedules the provided binding processor for processing and 
-   * immediately returns the context.
+   * Returns the set of <code>Id</code>s of currently managed BindingProcessor.
    * 
-   * @param aBindingProcessor
+   * @return the set of <code>Id</code>s of currently managed BindingProcessor.
    */
-  public ProcessingContext process(BindingProcessor aBindingProcessor);
-  
+  public Set<Id> getManagedIds();
+
   /**
-   * Removes a formerly added (by calling the process method) binding processor.
-   * @param bindingProcessor must not be null
+   * Schedule shutdown of this BindingProcessorManager.
    */
-  public void removeBindingProcessor(Id sessionId); 
-  
+  public void shutdown();
+
   /**
-   * A set of all managed binding processors.
-   * @return
+   * Immediately shutdown this BindingProcessorManager.
    */
-  public Set<Id> getManagedIds();
-      
-  public void shutdown();
-  
   public void shutdownNow();
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java
index bf9a63e2..eee80b03 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java
@@ -16,315 +16,283 @@
  */
 package at.gv.egiz.bku.binding;
 
-import at.gv.egiz.bku.conf.Configuration;
-import java.net.MalformedURLException;
-import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.configuration.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import at.gv.egiz.bku.jmx.ComponentMXBean;
+import at.gv.egiz.bku.jmx.ComponentState;
 import at.gv.egiz.bku.slcommands.SLCommandInvoker;
 import at.gv.egiz.bku.slexceptions.SLRuntimeException;
 import at.gv.egiz.bku.utils.binding.Protocol;
-import at.gv.egiz.stal.STAL;
 import at.gv.egiz.stal.STALFactory;
 
 /**
  * This class maintains all active BindingProcessor Objects. Currently, only
  * HTTPBinding is supported.
  */
-public class BindingProcessorManagerImpl implements BindingProcessorManager {
+public class BindingProcessorManagerImpl implements BindingProcessorManager, ComponentMXBean {
+  
+  public static long DEFAULT_MAX_ACCEPTED_AGE = 2 * 60 * 1000;
+  
+  public static int DEFAULT_CLEAN_UP_INTERVAL = 60;
 
-  public final static Protocol[] SUPPORTED_PROTOCOLS = { Protocol.HTTP,
-      Protocol.HTTPS };
+  private final Logger log = LoggerFactory.getLogger(BindingProcessorManagerImpl.class);
 
-  private static Log log = LogFactory.getLog(BindingProcessorManagerImpl.class);
+  private List<BindingProcessorFactory> factories = Collections.emptyList();
 
-  /** spring injected config
-   * Passed to created bindingprocessors, to replace their configuration */
-  protected Configuration config;
+  private Configuration configuration;
 
-  protected STALFactory stalFactory;
-  protected SLCommandInvoker commandInvokerClass;
+  private STALFactory stalFactory;
+  
+  private SLCommandInvoker commandInvoker;
   
-  private RemovalStrategy removalStrategy;
-  private ExecutorService executorService;
-  private Map<Id, ProcessingContext> contextMap = Collections.synchronizedMap(new HashMap<Id, ProcessingContext>());
-//  private Map<Id, MapEntityWrapper> bindingProcessorMap = Collections
-//      .synchronizedMap(new HashMap<Id, MapEntityWrapper>());
+  private ExecutorService executorService = Executors.newCachedThreadPool();
 
+  private Map<Id, BindingProcessorFuture> submittedFutures = Collections
+      .synchronizedMap(new HashMap<Id, BindingProcessorFuture>());
+  
+  private int cleanUpInterval = DEFAULT_CLEAN_UP_INTERVAL; 
+  
+  private long maxAcceptedAge = DEFAULT_MAX_ACCEPTED_AGE;
+   
+  private ScheduledExecutorService cleanUpService = Executors
+      .newSingleThreadScheduledExecutor();
+  
+  public BindingProcessorManagerImpl() {
+    cleanUpService.scheduleAtFixedRate(new CleanUpTask(), cleanUpInterval,
+        cleanUpInterval, TimeUnit.SECONDS);
+  }
+  
   /**
-   * Container to hold a Future and Bindingprocessor object as map value.
-   * 
-   * @author wbauer
-   * @see BindingProcessorManagerImpl#bindingProcessorMap
+   * @return the configuration
    */
-//  static class MapEntityWrapper {
-//    private Future<?> future;
-//    private BindingProcessor bindingProcessor;
-//
-//    public MapEntityWrapper(Future<?> future, BindingProcessor bindingProcessor) {
-//      if ((bindingProcessor == null) || (future == null)) {
-//        throw new NullPointerException("Argument must not be null");
-//      }
-//      this.bindingProcessor = bindingProcessor;
-//      this.future = future;
-//    }
-//
-//    public Future<?> getFuture() {
-//      return future;
-//    }
-//
-//    public BindingProcessor getBindingProcessor() {
-//      return bindingProcessor;
-//    }
-//
-//    public int hashCode() {
-//      return bindingProcessor.getId().hashCode();
-//    }
-//
-//    public boolean equals(Object other) {
-//      if (other instanceof MapEntityWrapper) {
-//        MapEntityWrapper o = (MapEntityWrapper) other;
-//        return (o.bindingProcessor.getId().equals(bindingProcessor.getId()));
-//      } else {
-//        return false;
-//      }
-//    }
-//  }
+  public Configuration getConfiguration() {
+    return configuration;
+  }
 
   /**
-   * 
-   * @param fab
-   *          must not be null
-   * @param ci
-   *          must not be null (prototype to generate new instances)
+   * @param configuration the configuration to set
    */
-  public BindingProcessorManagerImpl(STALFactory fab, SLCommandInvoker ci, Configuration conf) {
-    if (fab == null) {
-      throw new NullPointerException("STALFactory must not be null");
-    }
-    stalFactory = fab;
-    if (ci == null) {
-      throw new NullPointerException("SLCommandInvoker must not be null");
-    }
-    commandInvokerClass = ci;
-    config = conf;
-    executorService = Executors.newCachedThreadPool();
+  public void setConfiguration(Configuration configuration) {
+    this.configuration = configuration;
   }
 
   /**
-   * 
-   * @return the STALFactory currently used.
+   * @return the factoryMap
    */
-  public STALFactory getStalFactory() {
-    return stalFactory;
+  public List<BindingProcessorFactory> getFactories() {
+    return factories;
   }
 
   /**
-   * Sets the STALFactory to be used.
-   * 
-   * @param stalFactory
+   * @param factoryMap the factoryMap to set
    */
-  public void setStalFactory(STALFactory stalFactory) {
-    this.stalFactory = stalFactory;
+  public void setFactories(List<BindingProcessorFactory> factories) {
+    this.factories = factories;
   }
 
   /**
-   * Could be used to setup a new executor service during application stratup.
+   * Sets a SLCommandInvoker prototype used to create a SLCommandInvoker for
+   * initialization of a BindingProcessor.
    * 
-   * @param executorService
+   * @param invoker
+   */
+  public void setSlCommandInvoker(SLCommandInvoker invoker) {
+    commandInvoker = invoker;
+  }
+
+  /**
+   * @return the SLCommandInvoker prototype used to create a SLCommandInvoker
+   *         for initialization of a BindingProcessor.
    */
-  public void setExecutorService(ExecutorService executorService) {
-    this.executorService = executorService;
+  public SLCommandInvoker getCommandInvoker() {
+    return commandInvoker;
   }
 
-  public void setRemovalStrategy(RemovalStrategy aStrategy) {
-    removalStrategy = aStrategy;
+  /**
+   * @return the STALFactory currently used.
+   */
+  public STALFactory getStalFactory() {
+    return stalFactory;
   }
 
-  public RemovalStrategy getRemovlaStrategy() {
-    return removalStrategy;
+  /**
+   * Sets the STALFactory used to create a STAL implementation for initialization of
+   * a BindingProcessor.
+   * 
+   * @param stalFactory
+   */
+  public void setStalFactory(STALFactory stalFactory) {
+    this.stalFactory = stalFactory;
   }
 
+  /* (non-Javadoc)
+   * @see at.gv.egiz.bku.binding.BindingProcessorManager#shutdown()
+   */
+  @Override
   public void shutdown() {
-    log.info("Shutting down the BindingProcessorManager");
+    log.info("Shutting down the BindingProcessorManager.");
     executorService.shutdown();
+    cleanUpService.shutdown();
   }
 
+  /* (non-Javadoc)
+   * @see at.gv.egiz.bku.binding.BindingProcessorManager#shutdownNow()
+   */
+  @Override
   public void shutdownNow() {
     log.info("Shutting down the BindingProcessorManager NOW!");
+    cleanUpService.shutdownNow();
     executorService.shutdownNow();
-    log.debug("Number of binding contexts currently managed: "
-      + contextMap.size());
-//        + bindingProcessorMap.size());
+    log.debug("Number of binding contexts currently managed: {}.", submittedFutures.size());
     if (log.isDebugEnabled()) {
-      for (ProcessingContext ctx : contextMap.values()) {
-        Id bpId = ctx.getBindingProcessor().getId();
-        Future future = ctx.getFuture();
-        log.debug(bpId + " cancelled: " + future.isCancelled());
-        log.debug(bpId + " done: " + future.isDone());
+      for (BindingProcessorFuture future : submittedFutures.values()) {
+        if (future.isCancelled()) {
+          log.debug("BindingProcessor {} is cancelled.", future.getBindingProcessor().getId());
+        } else {
+          log.debug("BindingProcessor {} is done: {}.", future.getBindingProcessor().getId(), future.isDone());
+        }
       }
-//      for (Iterator<MapEntityWrapper> it = bindingProcessorMap.values()
-//          .iterator(); it.hasNext();) {
-//        MapEntityWrapper entry = it.next();
-//        log.debug(entry.getBindingProcessor().getId() + ": isDone: "
-//            + entry.getFuture().isDone());
-//        log.debug(entry.getBindingProcessor().getId() + ": isCanceled: "
-//            + entry.getFuture().isCancelled());
-//      }
     }
   }
 
-  /**
-   * Uses the default locale
+  /* (non-Javadoc)
+   * @see at.gv.egiz.bku.binding.BindingProcessorManager#createBindingProcessor(java.lang.String, java.lang.String)
    */
-  public BindingProcessor createBindingProcessor(String srcUrl,
-      String aSessionId) throws MalformedURLException {
-    return createBindingProcessor(srcUrl, aSessionId, null);
+  @Override
+  public BindingProcessor createBindingProcessor(String protocol) {
+    Protocol p = Protocol.fromString(protocol);
+    for (BindingProcessorFactory factory : factories) {
+      if (factory.getSupportedProtocols().contains(p)) {
+        return factory.createBindingProcessor();
+      }
+    }
+    throw new IllegalArgumentException();
   }
 
-  /**
-   * FactoryMethod creating a new BindingProcessor object.
-   * 
-   * @param protocol
-   *          must not be null
-   * @throws MalformedURLException
+  /* (non-Javadoc)
+   * @see at.gv.egiz.bku.binding.BindingProcessorManager#createBindingProcessor(java.lang.String, java.lang.String, java.util.Locale)
    */
-  public BindingProcessor createBindingProcessor(String srcUrl,
-      String aSessionId, Locale locale) throws MalformedURLException {
-    URL url = new URL(srcUrl);
-    String low = url.getProtocol().toLowerCase();
-    Protocol proto = null;
-    for (int i = 0; i < SUPPORTED_PROTOCOLS.length; i++) {
-      if (SUPPORTED_PROTOCOLS[i].toString().equals(low)) {
-        proto = SUPPORTED_PROTOCOLS[i];
-        break;
-      }
-    }
-    if (proto == null) {
-      throw new UnsupportedOperationException();
-    }
-    BindingProcessor bindingProcessor = new HTTPBindingProcessor(aSessionId,
-        commandInvokerClass.newInstance(), url);
-    stalFactory.setLocale(locale);
-    STAL stal = stalFactory.createSTAL();
-    bindingProcessor.init(stal, commandInvokerClass.newInstance(), config);
-    if (locale != null) {
-      bindingProcessor.setLocale(locale);
-//      stal.setLocale(locale);
-    }
+  @Override
+  public BindingProcessor createBindingProcessor(String protocol, Locale locale) {
+    BindingProcessor bindingProcessor = createBindingProcessor(protocol);
+    bindingProcessor.setLocale(locale);
     return bindingProcessor;
   }
 
-  /**
-   * @return the bindingprocessor object for this id or null if no
-   *         bindingprocessor was found.
+  /* (non-Javadoc)
+   * @see at.gv.egiz.bku.binding.BindingProcessorManager#process(java.lang.String, at.gv.egiz.bku.binding.BindingProcessor)
    */
-    @Override
-  public BindingProcessor getBindingProcessor(Id aId) {
-//    if (bindingProcessorMap.get(aId) != null) {
-//      return bindingProcessorMap.get(aId).getBindingProcessor();
-    ProcessingContext ctx = contextMap.get(aId);
-    if (ctx != null) {
-      return ctx.getBindingProcessor();
-    } else {
-      return null;
+  @Override
+  public BindingProcessorFuture process(Id id, BindingProcessor bindingProcessor) {
+    
+    log.trace("Initialize BindingProcessor for processing.");
+    bindingProcessor.init(id.toString(), stalFactory.createSTAL(), commandInvoker.newInstance());
+    
+    BindingProcessorFuture future = new BindingProcessorFuture(bindingProcessor);
+    if (submittedFutures.containsKey(bindingProcessor.getId())) {
+      log.error("BindingProcessor with with id {} already submitted.", id);
+      throw new SLRuntimeException("BindingProcessor with with id " + id
+          + " already submitted.");
     }
+    
+    try {
+      log.debug("Submitting BindingProcessor {} for processing.", id);
+      executorService.execute(future);
+      submittedFutures.put(bindingProcessor.getId(), future);
+    } catch (RejectedExecutionException e) {
+      log.error("BindingProcessor {} processing rejected.", id, e);
+      throw new SLRuntimeException("BindingProcessor {} " + id + " processing rejected.", e);
+    }
+    
+    return future;
+    
   }
 
-  /**
-   * 
+  /* (non-Javadoc)
+   * @see at.gv.egiz.bku.binding.BindingProcessorManager#getBindingProcessor(at.gv.egiz.bku.binding.Id)
    */
-    @Override
-  public void setSTALFactory(STALFactory aStalFactory) {
-    if (aStalFactory == null) {
-      throw new NullPointerException("Cannot set STALFactory to null");
+  @Override
+  public BindingProcessor getBindingProcessor(Id id) {
+    BindingProcessorFuture future = submittedFutures.get(id);
+    if (future != null) {
+      return future.getBindingProcessor();
+    } else {
+      return null;
     }
-    stalFactory = aStalFactory;
   }
 
-  /**
-   * Causes the BindingProcessorManager to manage the provided BindingProcessor
-   * Creates a processing context,
-   * schedules the provided binding processor for processing and 
-   * immediately returns the context.
-   * 
-   * @param aBindingProcessor
-   *          must not be null
+  /* (non-Javadoc)
+   * @see at.gv.egiz.bku.binding.BindingProcessorManager#removeBindingProcessor(at.gv.egiz.bku.binding.Id)
    */
   @Override
-  public ProcessingContext process(BindingProcessor aBindingProcessor) {
-    if (contextMap.containsKey(aBindingProcessor.getId())) {
-//    if (bindingProcessorMap.containsKey(aBindingProcessor.getId())) {
-      log.fatal("Clashing ids, cannot process bindingprocessor with id:"
-          + aBindingProcessor.getId());
-      throw new SLRuntimeException(
-          "Clashing ids, cannot process bindingprocessor with id:"
-              + aBindingProcessor.getId());
+  public void removeBindingProcessor(Id id) {
+    BindingProcessorFuture future = submittedFutures.remove(id);
+    if (future != null) {
+      if (!future.isDone()) {
+        log.debug("Interrupting BindingProcessor {}.", id );
+        future.cancel(true);
+      }
+      if (log.isInfoEnabled()) {
+        Object[] args = {id, future.getExecutionTime() / 1000.0, future.getAge() / 1000.0};
+        log.info("Removing BindingProcessor {} (active:{}s/age:{}s).", args);
+      }
     }
-    log.debug("processing bindingprocessor: " + aBindingProcessor.getId());
-    Future<?> f = executorService.submit(aBindingProcessor);
-    ProcessingContext ctx = new ProcessingContext(aBindingProcessor, f);
-    contextMap.put(aBindingProcessor.getId(), ctx);
-//    bindingProcessorMap.put(aBindingProcessor.getId(), new MapEntityWrapper(f,
-//        aBindingProcessor));
-    return ctx;
   }
 
+  /* (non-Javadoc)
+   * @see at.gv.egiz.bku.binding.BindingProcessorManager#getManagedIds()
+   */
   @Override
-  public void setSLCommandInvoker(SLCommandInvoker invoker) {
-    commandInvokerClass = invoker;
+  public Set<Id> getManagedIds() {
+    return Collections.unmodifiableSet(new HashSet<Id>(submittedFutures.keySet()));
   }
 
+  /* (non-Javadoc)
+   * @see at.gv.egiz.bku.jmx.ComponentMXBean#checkComponentState()
+   */
   @Override
-  public void removeBindingProcessor(Id sessionId) {
-    log.debug("Removing binding processor: " + sessionId);
-    ProcessingContext ctx = contextMap.get(sessionId);
-    if (ctx == null) {
-      log.warn("no processing context to remove for session " + sessionId);
-      return;
-    }
-    Future f = ctx.getFuture();
-    
-//    MapEntityWrapper wrapper = bindingProcessorMap.get(sessionId);
-//    if (wrapper == null) {
-//      return;
-//    }
-//    Future<?> f = wrapper.getFuture();
-    
-    if (!f.isDone()) {
-      log.trace("canceling " + sessionId);
-      f.cancel(true);
-    }
-    contextMap.remove(sessionId);
-//    bindingProcessorMap.remove(sessionId);
+  public ComponentState checkComponentState() {
+    return new ComponentState(true);
   }
-
-  @Override
-  public Set<Id> getManagedIds() {
-    Set<Id> result = new HashSet<Id>();
-    synchronized (contextMap) {
-      for (Id id : contextMap.keySet()) {
-        result.add(id);
+  
+  public class CleanUpTask implements Runnable {
+    
+    @Override
+    public void run() {
+      Collection<BindingProcessorFuture> futures = submittedFutures.values();
+      List<Id> toBeRemoved = new ArrayList<Id>();
+      int active = 0;
+      for(BindingProcessorFuture future : futures) {
+        BindingProcessor bindingProcessor = future.getBindingProcessor();
+        if (!future.isDone()) {
+          active++;
+        }
+        if ((bindingProcessor.getLastAccessTime().getTime() - System
+            .currentTimeMillis()) > maxAcceptedAge) {
+          toBeRemoved.add(bindingProcessor.getId());
+        }
+      }
+      for (Id id : toBeRemoved) {
+        removeBindingProcessor(id);
       }
     }
-//    synchronized (bindingProcessorMap) {
-//      for (Iterator<Id> it = bindingProcessorMap.keySet().iterator(); it
-//          .hasNext();) {
-//        result.add(it.next());
-//      }
-//    }
-    return result;
+    
   }
-}
\ No newline at end of file
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataURLConnectionFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataURLConnectionFactory.java
new file mode 100644
index 00000000..d6e5c701
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataURLConnectionFactory.java
@@ -0,0 +1,26 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.binding;
+
+import java.net.URL;
+
+public abstract class DataURLConnectionFactory {
+
+  public abstract DataUrlConnection openConnection(URL url);
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java
index d3945253..f267f9a9 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java
@@ -16,18 +16,9 @@
  */
 package at.gv.egiz.bku.binding;
 
-import at.gv.egiz.bku.conf.Configurator;
+import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.util.Properties;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLSocketFactory;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.bku.slexceptions.SLRuntimeException;
 
 /**
  * Used to handle DataUrl connections as specified in the CCE's HTTP protocol binding. 
@@ -35,77 +26,37 @@ import at.gv.egiz.bku.slexceptions.SLRuntimeException;
  */
 public class DataUrl {
 
-  private static Log log = LogFactory.getLog(DataUrl.class);
-  private static DataUrlConnectionSPI connection;
-  private static Properties configuration;
-  private static SSLSocketFactory sslSocketFactory;
-  private static HostnameVerifier hostNameVerifier;
-  private URL url;
-
-  /** spring injected config, to replace configuration */
-  //private Configuration config;
-
+  private static DataURLConnectionFactory connectionFactory;
+  
   /**
-   * Sets the default DataUrlConnection implementation
-   * @param aClass must not be null
+   * @return the connectionFactory
    */
-  static void setDataUrlConnectionImpl(DataUrlConnectionSPI conn) {
-    if (conn != null) {
-      connection = conn;
-    }
-  }
-
-  public DataUrl(String aUrlString) throws MalformedURLException {
-    url = new URL(aUrlString);
-    if (connection == null) {
-      log.debug("Using default DataURLConnection class");
-      connection = new DataUrlConnectionImpl();
-    }
-    connection.setConfiguration(configuration);
-    connection.setSSLSocketFactory(sslSocketFactory);
-    connection.setHostnameVerifier(hostNameVerifier);
+  public static DataURLConnectionFactory getConnectionFactory() {
+    return connectionFactory;
   }
 
-  public DataUrlConnection openConnection() {
-    try {
-      log.debug("Opening dataurl connection");
-      DataUrlConnectionSPI retVal = connection.newInstance();
-      retVal.init(url);
-      return retVal;
-    } catch (Exception e) {
-      log.error(e);
-      throw new SLRuntimeException("Cannot instantiate a dataurlconnection:", e);
-    }
-  }
-
-
   /**
-   * set configuration for all subsequently instantiated DataURL objects
-   * @param props
+   * @param connectionFactory the connectionFactory to set
    */
-  public static void setConfiguration(Properties props) {
-    configuration = props;
-    if (configuration != null) {
-      String className = configuration.getProperty(Configurator.DATAURLCONNECTION_CONFIG_P);
-      if (className != null) {
-        log.warn("Set DataURLConnection class not supported!");
-      }
-    }
+  public static void setConnectionFactory(
+      DataURLConnectionFactory connectionFactory) {
+    DataUrl.connectionFactory = connectionFactory;
   }
 
   /**
-   * set SSLSocketFactory for all subsequently instantiated DataURL objects
-   * @param socketFactory
+   * The URL.
    */
-  public static void setSSLSocketFactory(SSLSocketFactory socketFactory) {
-    sslSocketFactory = socketFactory;
+  private URL url;
+
+  public DataUrl(String spec) throws MalformedURLException {
+    url = new URL(spec);
   }
 
-  /**
-   * set HostnameVerifier for all subsequently instantiated DataURL objects
-   * @param hostNameVerifier
-   */
-  public static void setHostNameVerifier(HostnameVerifier hostNameVerifier) {
-    DataUrl.hostNameVerifier = hostNameVerifier;
+  public DataUrlConnection openConnection() throws IOException {
+    if (connectionFactory != null) {
+      return connectionFactory.openConnection(url);
+    } else {
+      return new DataUrlConnectionImpl(url);
+    }
   }
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java
index 384cf71c..13b1e627 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java
@@ -1,82 +1,92 @@
 /*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package at.gv.egiz.bku.binding;
 
 import java.io.IOException;
-import java.io.InputStream;
 import java.net.SocketTimeoutException;
 import java.net.URL;
-import java.security.cert.X509Certificate;
+import java.net.URLConnection;
 
 import at.gv.egiz.bku.slcommands.SLResult;
 
 /**
- * Transmit a security layer result to DataURL via HTTP POST, encoded as multipart/form-data. 
- * The HTTP header user-agent is set to <em>citizen-card-environment/1.2 BKU2 1.0</em>.
- * The form-parameter ResponseType is set to <em>HTTP-Security-Layer-RESPONSE</em>.
- * All other headers/parameters are set by the caller.
+ * Transmit a security layer result to DataURL via HTTP POST, encoded as
+ * multipart/form-data. The HTTP header user-agent is set to
+ * <em>citizen-card-environment/1.2 BKU2 1.0</em>. The form-parameter
+ * ResponseType is set to <em>HTTP-Security-Layer-RESPONSE</em>. All other
+ * headers/parameters are set by the caller.
  * 
  * @author clemens
  */
-public interface DataUrlConnection {
+public abstract class DataUrlConnection {
+
+  public static final String FORMPARAM_RESPONSETYPE = "ResponseType";
+  public static final String DEFAULT_RESPONSETYPE = "HTTP-Security-Layer-RESPONSE";
+  public static final String FORMPARAM_XMLRESPONSE = "XMLResponse";
+  public static final String FORMPARAM_BINARYRESPONSE = "BinaryResponse";
+
+  public static final String XML_RESPONSE_ENCODING = "UTF-8";
 
-    public static final String FORMPARAM_RESPONSETYPE = "ResponseType";
-    public static final String DEFAULT_RESPONSETYPE = "HTTP-Security-Layer-RESPONSE";
-    public static final String FORMPARAM_XMLRESPONSE = "XMLResponse";
-    public static final String FORMPARAM_BINARYRESPONSE = "BinaryResponse";
-    
-    public static final String XML_RESPONSE_ENCODING = "UTF-8";
+  /**
+   * The URL to send responses and retrieve any further requests.
+   */
+  protected URL url;
 
-    
-    public String getProtocol();
-    
-    public URL getUrl();
-    
-    /**
-     * Set a HTTP Header.
-     * @param key
-     * @param value multiple values are assumed to have the correct formatting (comma-separated list)
-     */
-    public void setHTTPHeader(String key, String value);
+  /**
+   * Constructs a DataURL connection to the specified URL.
+   * 
+   * @param url
+   *          the URL to send responses and retrieve any further requests
+   */
+  protected DataUrlConnection(URL url) {
+    this.url = url;
+  }
 
-    /**
-     * Set a form-parameter.
-     * @param name
-     * @param data
-     * @param contentType may be null
-     * @param charSet may be null
-     * @param transferEncoding may be null
-     */
-    public void setHTTPFormParameter(String name, InputStream data, String contentType, String charSet, String transferEncoding);
-    
-    /**
-     * @pre httpHeaders != null
-     * @throws java.net.SocketTimeoutException
-     * @throws java.io.IOException
-     */
-    public void connect() throws SocketTimeoutException, IOException;
+  /**
+   * Returns the URL to send responses and retrieve any further requests.
+   * 
+   * @return the URL
+   */
+  public URL getURL() {
+    return url;
+  }
 
-    public X509Certificate getServerCertificate();
+  /**
+   * @see URLConnection#connect() 
+   */
+  public abstract void connect() throws SocketTimeoutException, IOException;
 
-    /**
-     * @pre connection != null
-     * @throws java.io.IOException
-     */
-    public void transmit(SLResult slResult) throws IOException;
+  /**
+   * Transmit the given <code>SLResult</code> to the resource identified by this
+   * URL.
+   * 
+   * @param slResult the <code>SLResult</code>
+   * @throws IOException if an I/O exception occurs
+   */
+  public abstract void transmit(SLResult slResult) throws IOException;
 
-    public DataUrlResponse getResponse() throws IOException;
+  /**
+   * Returns the <code>DataUrlResponse</code> received from the resource
+   * identified by this URL.
+   * 
+   * @return the DataUrlResponse received 
+   * 
+   * @throws IOException if an I/O exception occurs
+   */
+  public abstract DataUrlResponse getResponse() throws IOException;
+  
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java
index 93e5bb1c..1ce6d2cc 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java
@@ -26,29 +26,27 @@ import java.net.SocketTimeoutException;
 import java.net.URL;
 import java.net.URLEncoder;
 import java.nio.charset.Charset;
-import java.security.cert.X509Certificate;
+import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
 
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLPeerUnverifiedException;
 import javax.net.ssl.SSLSocketFactory;
 import javax.xml.transform.stream.StreamResult;
 
 import org.apache.commons.httpclient.methods.multipart.FilePart;
 import org.apache.commons.httpclient.methods.multipart.Part;
 import org.apache.commons.httpclient.methods.multipart.StringPart;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import at.gv.egiz.bku.binding.multipart.InputStreamPartSource;
 import at.gv.egiz.bku.binding.multipart.SLResultPart;
-import at.gv.egiz.bku.conf.Configurator;
 import at.gv.egiz.bku.slcommands.SLResult;
 import at.gv.egiz.bku.slcommands.SLResult.SLResultType;
 import at.gv.egiz.bku.slexceptions.SLRuntimeException;
@@ -62,168 +60,144 @@ import at.gv.egiz.bku.utils.binding.Protocol;
  * systems.
  * 
  */
-public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
+public class DataUrlConnectionImpl extends HttpsDataURLConnection {
 
-  private final static Log log = LogFactory.getLog(DataUrlConnectionImpl.class);
-  
-  public static final byte[] B_DEFAULT_RESPONSETYPE = DEFAULT_RESPONSETYPE.getBytes(Charset.forName("UTF-8"));
+  private final Logger log = LoggerFactory.getLogger(DataUrlConnectionImpl.class);
+
+  public static final byte[] B_DEFAULT_RESPONSETYPE = DEFAULT_RESPONSETYPE
+      .getBytes(Charset.forName("UTF-8"));
 
   /**
-   * Supported protocols are HTTP and HTTPS. 
+   * Supported protocols are HTTP and HTTPS.
    */
   public final static Protocol[] SUPPORTED_PROTOCOLS = { Protocol.HTTP,
       Protocol.HTTPS };
 
   /**
-   * The X509 certificate of the DataURL server.
-   */
-  protected X509Certificate serverCertificate;
-  
-  /**
-   * The protocol of the DataURL.
-   */
-  protected Protocol protocol;
-  
-  /**
-   * Use <code>application/x-www-form-urlencoded</code> instead of
-   * standard conform <code>application/x-www-form-urlencoded</code>.
+   * Use <code>application/x-www-form-urlencoded</code> instead of standard
+   * conform <code>application/x-www-form-urlencoded</code>.
    */
   protected boolean urlEncoded = true;
-  
-  /**
-   * The value of the DataURL.
-   */
-  protected URL url;
-  
+
   /**
    * The URLConnection used for communication with the DataURL server.
    */
   private HttpURLConnection connection;
-  
-  /**
-   * The HTTP request headers.
-   */
-  protected Map<String, String> requestHttpHeaders;
-  
+
   /**
    * The HTTP form parameters.
    */
-  protected ArrayList<HTTPFormParameter> httpFormParameter;
-  
+  protected List<HTTPFormParameter> httpFormParameter = new ArrayList<HTTPFormParameter>();
+
   /**
    * The boundary for multipart/form-data requests.
    */
   protected String boundary;
-  
-  /**
-   * The configuration properties.
-   */
-  protected Properties config = null;
-  
-  /**
-   * The SSLSocketFactory for HTTPS connections.
-   */
-  protected SSLSocketFactory sslSocketFactory;
-  
-  /**
-   * The HostnameVerifier for HTTPS connections. 
-   */
-  protected HostnameVerifier hostnameVerifier;
 
   /**
    * The response of the DataURL server.
    */
-  protected DataUrlResponse result;
+  protected DataUrlResponse response;
 
-  /* (non-Javadoc)
-   * @see at.gv.egiz.bku.binding.DataUrlConnection#getProtocol()
+  /**
+   * Constructs a new instance of this DataUrlConnection implementation.
+   * 
+   * @param url the URL 
+   * 
+   * @throws IOException if an I/O exception occurs
    */
-  public String getProtocol() {
+  public DataUrlConnectionImpl(URL url) throws IOException {
+    super(url);
+    
+    Protocol protocol = null;
+    for (int i = 0; i < SUPPORTED_PROTOCOLS.length; i++) {
+      if (SUPPORTED_PROTOCOLS[i].toString().equalsIgnoreCase(url.getProtocol())) {
+        protocol = SUPPORTED_PROTOCOLS[i];
+        break;
+      }
+    }
     if (protocol == null) {
-      return null;
+      throw new SLRuntimeException("Protocol " + url.getProtocol()
+          + " not supported for data url.");
     }
-    return protocol.toString();
+    connection = (HttpURLConnection) url.openConnection();
+    connection.setInstanceFollowRedirects(false);
+    
+    connection.setDoOutput(true);
+
+    
+    boundary = "--" + IdFactory.getInstance().createId().toString();
   }
 
-  /* (non-Javadoc)
+  @Override
+  public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
+    if (connection instanceof HttpsURLConnection) {
+      ((HttpsURLConnection) connection).setHostnameVerifier(hostnameVerifier);
+    }
+  }
+
+  @Override
+  public void setSSLSocketFactory(SSLSocketFactory socketFactory) {
+    if (connection instanceof HttpsURLConnection) {
+      ((HttpsURLConnection) connection).setSSLSocketFactory(socketFactory);
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
    * @see at.gv.egiz.bku.binding.DataUrlConnection#connect()
    */
   public void connect() throws SocketTimeoutException, IOException {
-    connection = (HttpURLConnection) url.openConnection();
-    if (connection instanceof HttpsURLConnection) {
-      log.trace("Detected ssl connection");
-      HttpsURLConnection https = (HttpsURLConnection) connection;
-      if (sslSocketFactory != null) {
-        log.debug("Setting custom ssl socket factory for ssl connection");
-        https.setSSLSocketFactory(sslSocketFactory);
-      } else {
-        log.trace("No custom socket factory set");
-      }
-      if (hostnameVerifier != null) {
-        log.debug("Setting custom hostname verifier");
-        https.setHostnameVerifier(hostnameVerifier);
-      }
-    } else {
-      log.trace("No secure connection with: " + url + " class="
-          + connection.getClass());
-    }
-    connection.setDoOutput(true);
     // Transfer-Encoding: chunked is problematic ...
     // e.g. https://issues.apache.org/bugzilla/show_bug.cgi?id=37794
     // ... therefore disabled.
     // connection.setChunkedStreamingMode(5*1024);
     if (urlEncoded) {
-      log.debug("Setting DataURL Content-Type to "
-          + HttpUtil.APPLICATION_URL_ENCODED);
+      log.debug("Setting DataURL Content-Type to {}.",
+          HttpUtil.APPLICATION_URL_ENCODED);
       connection.addRequestProperty(HttpUtil.HTTP_HEADER_CONTENT_TYPE,
           HttpUtil.APPLICATION_URL_ENCODED);
     } else {
-      log.debug("Setting DataURL Content-Type to "
-          + HttpUtil.MULTIPART_FOTMDATA_BOUNDARY);
+      log.debug("Setting DataURL Content-Type to {}.",
+          HttpUtil.MULTIPART_FOTMDATA_BOUNDARY);
       connection.addRequestProperty(HttpUtil.HTTP_HEADER_CONTENT_TYPE,
           HttpUtil.MULTIPART_FOTMDATA + HttpUtil.SEPERATOR[0]
               + HttpUtil.MULTIPART_FOTMDATA_BOUNDARY + "=" + boundary);
     }
-    Set<String> headers = requestHttpHeaders.keySet();
-    Iterator<String> headerIt = headers.iterator();
-    while (headerIt.hasNext()) {
-      String name = headerIt.next();
-      connection.setRequestProperty(name, requestHttpHeaders.get(name));
-    }
-    log.trace("Connecting to: " + url);
+    log.trace("Connecting to URL '{}'.", url);
     connection.connect();
-    if (connection instanceof HttpsURLConnection) {
-      HttpsURLConnection ssl = (HttpsURLConnection) connection;
-      X509Certificate[] certs = (X509Certificate[]) ssl.getServerCertificates();
-      if ((certs != null) && (certs.length >= 1)) {
-        log.trace("Server certificate: " + certs[0]);
-        serverCertificate = certs[0];
-      }
-    }
   }
 
   /* (non-Javadoc)
-   * @see at.gv.egiz.bku.binding.DataUrlConnection#getServerCertificate()
+   * @see at.gv.egiz.bku.binding.HttpsDataURLConnection#getServerCertificates()
    */
-  public X509Certificate getServerCertificate() {
-    return serverCertificate;
+  @Override
+  public Certificate[] getServerCertificates()
+      throws SSLPeerUnverifiedException, IllegalStateException {
+    if (connection instanceof HttpsURLConnection) {
+      return ((HttpsURLConnection) connection).getServerCertificates();
+    } else {
+      return null;
+    }
   }
 
   /* (non-Javadoc)
-   * @see at.gv.egiz.bku.binding.DataUrlConnection#setHTTPHeader(java.lang.String, java.lang.String)
+   * @see at.gv.egiz.bku.binding.HttpDataURLConnection#setHTTPHeader(java.lang.String, java.lang.String)
    */
+  @Override
   public void setHTTPHeader(String name, String value) {
-    if (name != null && value != null) {
-      requestHttpHeaders.put(name, value);
-    }
+    connection.setRequestProperty(name, value);
   }
 
   /* (non-Javadoc)
-   * @see at.gv.egiz.bku.binding.DataUrlConnection#setHTTPFormParameter(java.lang.String, java.io.InputStream, java.lang.String, java.lang.String, java.lang.String)
+   * @see at.gv.egiz.bku.binding.HttpDataURLConnection#setHTTPFormParameter(java.lang.String, java.io.InputStream, java.lang.String, java.lang.String, java.lang.String)
    */
+  @Override
   public void setHTTPFormParameter(String name, InputStream data,
       String contentType, String charSet, String transferEncoding) {
-    // if a content type is specified we have to switch to multipart/formdata encoding
+    // if a content type is specified we have to switch to multipart/form-data
+    // encoding
     if (contentType != null && contentType.length() > 0) {
       urlEncoded = false;
     }
@@ -231,27 +205,27 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
         charSet, transferEncoding));
   }
 
-  
-  
   /* (non-Javadoc)
    * @see at.gv.egiz.bku.binding.DataUrlConnection#transmit(at.gv.egiz.bku.slcommands.SLResult)
    */
+  @Override
   public void transmit(SLResult slResult) throws IOException {
-    log.trace("Sending data");
+    log.trace("Sending data.");
     if (urlEncoded) {
       //
       // application/x-www-form-urlencoded (legacy, SL < 1.2)
       //
-      
+
       OutputStream os = connection.getOutputStream();
-      OutputStreamWriter streamWriter = new OutputStreamWriter(os, HttpUtil.DEFAULT_CHARSET);
+      OutputStreamWriter streamWriter = new OutputStreamWriter(os,
+          HttpUtil.DEFAULT_CHARSET);
 
       // ResponseType
       streamWriter.write(FORMPARAM_RESPONSETYPE);
       streamWriter.write("=");
       streamWriter.write(URLEncoder.encode(DEFAULT_RESPONSETYPE, "UTF-8"));
       streamWriter.write("&");
-      
+
       // XMLResponse / Binary Response
       if (slResult.getResultType() == SLResultType.XML) {
         streamWriter.write(DataUrlConnection.FORMPARAM_XMLRESPONSE);
@@ -271,17 +245,18 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
         streamWriter.write("&");
         streamWriter.write(URLEncoder.encode(formParameter.getName(), "UTF-8"));
         streamWriter.write("=");
-        InputStreamReader reader = new InputStreamReader(formParameter.getData(), 
-            (formParameter.getCharSet() != null) 
-                ? formParameter.getCharSet()
-                : "UTF-8");  // assume request was application/x-www-form-urlencoded, formParam therefore UTF-8
+        InputStreamReader reader = new InputStreamReader(formParameter
+            .getData(), (formParameter.getCharSet() != null) ? formParameter
+            .getCharSet() : "UTF-8"); // assume request was
+                                      // application/x-www-form-urlencoded,
+                                      // formParam therefore UTF-8
         while ((len = reader.read(cbuf)) != -1) {
           urlEnc.write(cbuf, 0, len);
         }
         urlEnc.flush();
       }
       streamWriter.close();
-      
+
     } else {
       //
       // multipart/form-data (conforming to SL 1.2)
@@ -294,7 +269,7 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
           DEFAULT_RESPONSETYPE, "UTF-8");
       responseType.setTransferEncoding(null);
       parts.add(responseType);
-      
+
       // XMLResponse / Binary Response
       SLResultPart slResultPart = new SLResultPart(slResult,
           XML_RESPONSE_ENCODING);
@@ -307,7 +282,7 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
         slResultPart.setContentType(slResult.getMimeType());
       }
       parts.add(slResultPart);
-      
+
       // transfer parameters
       for (HTTPFormParameter formParameter : httpFormParameter) {
         InputStreamPartSource source = new InputStreamPartSource(null,
@@ -319,20 +294,21 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
       }
 
       OutputStream os = connection.getOutputStream();
-      Part.sendParts(os, parts.toArray(new Part[parts.size()]), boundary.getBytes());
+      Part.sendParts(os, parts.toArray(new Part[parts.size()]), boundary
+          .getBytes());
       os.close();
-      
+
     }
-    
+
     // MultipartRequestEntity PostMethod
     InputStream is = null;
     try {
       is = connection.getInputStream();
     } catch (IOException iox) {
-      log.info(iox);
+      log.info("Failed to get InputStream of HTTPUrlConnection.", iox);
     }
-    log.trace("Reading response");
-    result = new DataUrlResponse(url.toString(), connection.getResponseCode(),
+    log.trace("Reading response.");
+    response = new DataUrlResponse(url.toString(), connection.getResponseCode(),
         is);
     Map<String, String> responseHttpHeaders = new HashMap<String, String>();
     Map<String, List<String>> httpHeaders = connection.getHeaderFields();
@@ -349,105 +325,26 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
         responseHttpHeaders.put(key, valString);
       }
     }
-    result.setResponseHttpHeaders(responseHttpHeaders);
+    response.setResponseHttpHeaders(responseHttpHeaders);
   }
 
   @Override
   public DataUrlResponse getResponse() throws IOException {
-    return result;
-  }
-
-  /**
-   * inits protocol, url, httpHeaders, formParams
-   * 
-   * @param url
-   *          must not be null
-   */
-  @Override
-  public void init(URL url) {
-
-    for (int i = 0; i < SUPPORTED_PROTOCOLS.length; i++) {
-      if (SUPPORTED_PROTOCOLS[i].toString().equalsIgnoreCase(url.getProtocol())) {
-        protocol = SUPPORTED_PROTOCOLS[i];
-        break;
-      }
-    }
-    if (protocol == null) {
-      throw new SLRuntimeException("Protocol " + url.getProtocol()
-          + " not supported for data url");
-    }
-    this.url = url;
-    boundary = "--" + IdFactory.getInstance().createId().toString();
-    requestHttpHeaders = new HashMap<String, String>();
-    
-    if (config != null) {
-      String version = config.getProperty(Configurator.SIGNATURE_LAYOUT);
-      if ((version != null) && (!"".equals(version.trim()))) {
-    	log.debug("setting SignatureLayout header to " + version);
-        requestHttpHeaders.put(Configurator.SIGNATURE_LAYOUT, version);
-      } else {
-        log.debug("do not set SignatureLayout header");
-      }
-      String userAgent = config.getProperty(Configurator.USERAGENT_CONFIG_P, Configurator.USERAGENT_DEFAULT);
-      requestHttpHeaders.put(HttpUtil.HTTP_HEADER_USER_AGENT, userAgent);
-    } else {
-      requestHttpHeaders
-          .put(HttpUtil.HTTP_HEADER_USER_AGENT, Configurator.USERAGENT_DEFAULT);
-
-    }
-
-    httpFormParameter = new ArrayList<HTTPFormParameter>();
-
-  }
-
-  @Override
-  public DataUrlConnectionSPI newInstance() {
-    DataUrlConnectionSPI uc = new DataUrlConnectionImpl();
-    uc.setConfiguration(config);
-    uc.setSSLSocketFactory(sslSocketFactory);
-    uc.setHostnameVerifier(hostnameVerifier);
-    return uc;
+    return response;
   }
 
-  @Override
-  public URL getUrl() {
-    return url;
-  }
-
-  @Override
-  public void setConfiguration(Properties config) {
-    this.config = config;
-  }
-
-  @Override
-  public void setSSLSocketFactory(SSLSocketFactory socketFactory) {
-    this.sslSocketFactory = socketFactory;
-  }
-  
-  @Override
-  public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
-    this.hostnameVerifier = hostnameVerifier;
-  }
-  
   public class HTTPFormParameter {
 
-    private String name; 
-    
+    private String name;
+
     private InputStream data;
-    
+
     private String contentType;
-    
+
     private String charSet;
-    
+
     private String transferEncoding;
-    
-    /**
-     * @param name
-     * @param data
-     * @param contentType
-     * @param charSet
-     * @param transferEncoding
-     */
+
     public HTTPFormParameter(String name, InputStream data, String contentType,
         String charSet, String transferEncoding) {
       super();
@@ -466,7 +363,8 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
     }
 
     /**
-     * @param name the name to set
+     * @param name
+     *          the name to set
      */
     public void setName(String name) {
       this.name = name;
@@ -480,7 +378,8 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
     }
 
     /**
-     * @param data the data to set
+     * @param data
+     *          the data to set
      */
     public void setData(InputStream data) {
       this.data = data;
@@ -494,7 +393,8 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
     }
 
     /**
-     * @param contentType the contentType to set
+     * @param contentType
+     *          the contentType to set
      */
     public void setContentType(String contentType) {
       this.contentType = contentType;
@@ -508,7 +408,8 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
     }
 
     /**
-     * @param charSet the charSet to set
+     * @param charSet
+     *          the charSet to set
      */
     public void setCharSet(String charSet) {
       this.charSet = charSet;
@@ -522,13 +423,12 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
     }
 
     /**
-     * @param transferEncoding the transferEncoding to set
+     * @param transferEncoding
+     *          the transferEncoding to set
      */
     public void setTransferEncoding(String transferEncoding) {
       this.transferEncoding = transferEncoding;
     }
 
-    
-    
   }
-}
\ No newline at end of file
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionSPI.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionSPI.java
deleted file mode 100644
index f838b919..00000000
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionSPI.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package at.gv.egiz.bku.binding;
-
-import java.net.URL;
-import java.util.Properties;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLSocketFactory;
-
-/**
- * Prototype of a DataurlconnectionSPI
- * @author wbauer
- *
- */
-public interface DataUrlConnectionSPI extends DataUrlConnection {
-  
-  /**
-   * Returns a new instance of this class to handle a dataurl.
-   * Called by the factory each time the openConnection method is called. 
-   * @return
-   */
-  public DataUrlConnectionSPI newInstance();
-  
-  /**
-   * Initializes the DataUrlConnection
-   * @param url
-   */
-  public void init(URL url);
-  
-  /**
-   * Sets configuration parameters for this connection
-   * @param config
-   */
-  public void setConfiguration(Properties config);
-  
-  /**
-   * Sets the socketfactory to be used for ssl connections.
-   * @param socketFactory if null the socket factory will not be set explicitly
-   */
-  public void setSSLSocketFactory(SSLSocketFactory socketFactory);
-  
-  /**
-   * Sets the hostname verifier to be used,
-   * @param hostnameVerifier if null the default hostname verifier will be used
-   */
-  public void setHostnameVerifier(HostnameVerifier hostnameVerifier);
-
-
-}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/ExpiryRemover.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/ExpiryRemover.java
deleted file mode 100644
index d17a27c2..00000000
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/ExpiryRemover.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package at.gv.egiz.bku.binding;
-
-import java.util.Iterator;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * This class can be used to check the BindingProcessorManager for expired entries and remove them.
- * Should be run periodically. 
- *
- */
-public class ExpiryRemover implements RemovalStrategy {
-
-  private static Log log = LogFactory.getLog(ExpiryRemover.class);
-
-  protected BindingProcessorManager bindingProcessorManager;
-  // keep max 5 min.
-  protected long maxAcceptedAge = 1000 * 60 * 5;
-
-  @Override
-  public void execute() {
-    log.debug("Triggered Expiry Remover");
-    if (bindingProcessorManager == null) {
-      log.warn("Bindingprocessor not set, skipping removal");
-      return;
-    }
-    Set<Id> managedIds = bindingProcessorManager.getManagedIds();
-    for (Iterator<Id> it = managedIds.iterator(); it.hasNext();) {
-      Id bindId = it.next();
-      BindingProcessor bp = bindingProcessorManager.getBindingProcessor(bindId);
-      if (bp != null) {
-        if (bp.getLastAccessTime().getTime() < (System.currentTimeMillis() - maxAcceptedAge)) {
-          log.debug("Removing binding processor: " + bp.getId());
-          bindingProcessorManager.removeBindingProcessor(bp.getId());
-        }
-      }
-    }
-  }
-
-  public void setMaxAcceptedAge(long maxAcceptedAge) {
-    this.maxAcceptedAge = maxAcceptedAge;
-  }
-
-  @Override
-  public void setBindingProcessorManager(BindingProcessorManager bp) {
-    bindingProcessorManager = bp;
-  }
-
-}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLDereferencer.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLDereferencer.java
new file mode 100644
index 00000000..2f62775b
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLDereferencer.java
@@ -0,0 +1,71 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.binding;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.bku.utils.urldereferencer.StreamData;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
+
+public class FormDataURLDereferencer implements URLDereferencer {
+  
+  public final static String PROTOCOL = "formdata";
+  
+  private final Logger log = LoggerFactory.getLogger(FormDataURLDereferencer.class);
+
+  private URLDereferencer urlDereferencer;
+  
+  private FormDataURLSupplier formDataURLSupplier;
+  
+  public FormDataURLDereferencer(URLDereferencer urlDereferencer, FormDataURLSupplier formDataURLSupplier) {
+    this.urlDereferencer = urlDereferencer;
+    this.formDataURLSupplier = formDataURLSupplier;
+  }
+
+  @Override
+  public StreamData dereference(String url)
+      throws IOException {
+    
+    String urlString = url.toLowerCase().trim();
+    if (urlString.startsWith(PROTOCOL)) {
+      log.debug("Requested to dereference a formdata url.");
+      return dereferenceFormData(url);
+    } else {
+      return urlDereferencer.dereference(url);
+    }
+    
+  }
+
+  protected StreamData dereferenceFormData(String url) throws IOException {
+    log.debug("Dereferencing formdata url: {}.", url);
+    String[] parts = url.split(":", 2);
+
+    String contentType = formDataURLSupplier.getFormDataContentType(parts[1]);
+    InputStream is = formDataURLSupplier.getFormData(parts[1]);
+    if (is != null) {
+      return new StreamData(url, contentType, is);
+    }
+    throw new IOException("Cannot dereference URL: '" + url + "' not found.");
+  }
+
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLSupplier.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLSupplier.java
new file mode 100644
index 00000000..a248e683
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLSupplier.java
@@ -0,0 +1,27 @@
+/*
+* Copyright 2008 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package at.gv.egiz.bku.binding;
+
+import java.io.InputStream;
+
+public interface FormDataURLSupplier {
+
+  public InputStream getFormData(String aParameterName);
+  
+  public String getFormDataContentType(String aParameterName);
+  
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java
index e39addb5..db422498 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java
@@ -1,844 +1,35 @@
 /*
- * Copyright 2008 Federal Chancellery Austria and
- * Graz University of Technology
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package at.gv.egiz.bku.binding;
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
-import iaik.utils.Base64InputStream;
+package at.gv.egiz.bku.binding;
 
-import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URL;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 
-import javax.net.ssl.SSLHandshakeException;
-import javax.xml.transform.Templates;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.URIResolver;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.bku.slcommands.ErrorResult;
-import at.gv.egiz.bku.slcommands.SLCommand;
-import at.gv.egiz.bku.slcommands.SLCommandContext;
-import at.gv.egiz.bku.slcommands.SLCommandFactory;
-import at.gv.egiz.bku.slcommands.SLCommandInvoker;
-import at.gv.egiz.bku.slcommands.SLResult;
-import at.gv.egiz.bku.slcommands.SLSourceContext;
-import at.gv.egiz.bku.slcommands.SLTargetContext;
-import at.gv.egiz.bku.slcommands.impl.ErrorResultImpl;
-import at.gv.egiz.bku.slexceptions.SLBindingException;
-import at.gv.egiz.bku.slexceptions.SLException;
-import at.gv.egiz.bku.slexceptions.SLRuntimeException;
-import at.gv.egiz.bku.utils.StreamUtil;
-import at.gv.egiz.bku.utils.binding.Protocol;
-import at.gv.egiz.bku.utils.urldereferencer.FormDataURLSupplier;
-import at.gv.egiz.bku.utils.urldereferencer.SimpleFormDataContextImpl;
-import at.gv.egiz.bku.utils.urldereferencer.StreamData;
-import at.gv.egiz.bku.utils.urldereferencer.URIResolverAdapter;
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
-import at.gv.egiz.stal.QuitRequest;
-import at.gv.egiz.stal.STALRequest;
-
-/**
- * Class performing the HTTP binding as defined by the CCE specification.
- * Currently a huge monolithic class.
- * 
- * @TODO refactor
- */
-@SuppressWarnings("unchecked")
-public class HTTPBindingProcessor extends AbstractBindingProcessor implements
-		FormDataURLSupplier {
-
-	private static Log log = LogFactory.getLog(HTTPBindingProcessor.class);
-
-	private static enum State {
-		INIT, PROCESS, DATAURL, TRANSFORM, FINISHED
-	};
-
-	public final static Collection<String> XML_REQ_TRANSFER_ENCODING = Arrays
-			.asList(new String[] { "binary" });
-
-	protected static String XML_MIME_TYPE = "text/xml";
-	protected static String BINARY_MIME_TYPE = "application/octet-stream";
-
-	/**
-	 * If null everything is ok and the result is taken from the command invoker.
-	 */
-	protected SLException bindingProcessorError;
-	protected SLCommandInvoker commandInvoker;
-	protected DataUrlResponse dataUrlResponse;
-	protected Map<String, String> headerMap = Collections.EMPTY_MAP;
-	protected SLCommand slCommand;
-	protected Map<String, FormParameter> formParameterMap = new HashMap<String, FormParameter>();
-	protected SLSourceContext srcContex = new SLSourceContext();
-	protected SLTargetContext targetContext = new SLTargetContext();
-	protected URL srcUrl;
-	protected State currentState = State.INIT;
-	protected Templates templates = null;
-	protected String resultContentType = null;
-	protected SLResult slResult = null;
-	protected int responseCode = 200;
-	protected Map<String, String> responseHeaders = Collections.EMPTY_MAP;
-	protected Locale locale = Locale.getDefault();
-	protected boolean finished = false;
-
-	/**
-	 * 
-	 * @param id
-	 *          may be null. In this case a new session id will be created.
-	 * @param cmdInvoker
-	 *          must not be null;
-	 */
-	public HTTPBindingProcessor(String id, SLCommandInvoker cmdInvoker, URL source) {
-		super(id);
-		this.srcUrl = source;
-		Protocol protocol = Protocol.fromString(source.getProtocol());
-		if ((protocol != Protocol.HTTP) && (protocol != Protocol.HTTPS)) {
-			throw new SLRuntimeException("Protocol not supported: " + protocol);
-		}
-		if (cmdInvoker == null) {
-			throw new NullPointerException("Commandinvoker cannot be set to null");
-		}
-		commandInvoker = cmdInvoker;
-		srcContex.setSourceUrl(source);
-		srcContex.setSourceIsDataURL(false);
-	}
-
-	//----------------------------------------------------------------------------
-	// ----------- BEGIN CONVENIENCE METHODS -----------
-
-	protected void sendSTALQuit() {
-		log.info("Sending QUIT command to STAL");
-		List<STALRequest> quit = new ArrayList<STALRequest>(1);
-		quit.add(new QuitRequest());
-		getSTAL().handleRequest(quit);
-	}
-
-	protected String getFormParameterAsString(String formParameterName) {
-		FormParameter fp = formParameterMap.get(formParameterName);
-		return getFormParameterAsString(fp);
-	}
-
-	protected String getFormParameterAsString(FormParameter fp) {
-		if (fp == null) {
-			return null;
-		}
-		try {
-			return StreamUtil.asString(fp.getFormParameterValue(), HttpUtil
-					.getCharset(fp.getFormParameterContentType(), true));
-		} catch (IOException e) {
-			return null;
-		}
-	}
-
-	protected String getDataUrl() {
-		return getFormParameterAsString(FixedFormParameters.DATAURL);
-	}
-
-	protected String getStyleSheetUrl() {
-		return getFormParameterAsString(FixedFormParameters.STYLESHEETURL);
-	}
-
-	protected List<FormParameter> getFormParameters(String parameterNamePostfix) {
-		List<FormParameter> resultList = new ArrayList<FormParameter>();
-		for (Iterator<String> fpi = formParameterMap.keySet().iterator(); fpi
-				.hasNext();) {
-			String paramName = fpi.next();
-			if (paramName.endsWith(parameterNamePostfix)) {
-				resultList.add(formParameterMap.get(paramName));
-			}
-		}
-		return resultList;
-	}
-
-	protected List<FormParameter> getTransferHeaders() {
-		return getFormParameters("__");
-	}
-
-	protected List<FormParameter> getTransferForms() {
-		List<FormParameter> resultList = new ArrayList<FormParameter>();
-		for (Iterator<String> fpi = formParameterMap.keySet().iterator(); fpi
-				.hasNext();) {
-			String paramName = fpi.next();
-			if ((paramName.endsWith("_")) && (!paramName.endsWith("__"))) {
-				resultList.add(formParameterMap.get(paramName));
-			}
-		}
-		return resultList;
-	}
-
-	protected void closeDataUrlConnection() {
-		log.debug("Closing data url input stream");
-		if (dataUrlResponse == null) {
-			return;
-		}
-		InputStream is = dataUrlResponse.getStream();
-		if (is != null) {
-			try {
-				is.close();
-			} catch (IOException e) {
-				log.info("Error closing input stream to dataurl server:" + e);
-			}
-		}
-	}
-
-	//----------------------------------------------------------------------------
-	// ----------- END CONVENIENCE METHODS -----------
-
-	//----------------------------------------------------------------------------
-	// -- BEGIN Methods that handle the http binding activities as defined in the
-	// activity diagram --
-
-	protected void init() {
-		log.info("Starting Bindingprocessor in Thread: "
-				+ Thread.currentThread().getId());
-		if (bindingProcessorError != null) {
-			log.debug("Detected binding processor error, sending quit command");
-			// sendSTALQuit();
-			currentState = State.FINISHED;
-		} else if (slCommand == null) {
-			log.error("SLCommand not set (consumeRequest not called ??)");
-			bindingProcessorError = new SLException(2000);
-			// sendSTALQuit();
-			currentState = State.FINISHED;
-		} else {
-			currentState = State.PROCESS;
-		}
-	}
-
-	protected void processRequest() {
-		log.debug("Entered State: " + State.PROCESS);
-		log.debug("Processing command: " + slCommand);
-		commandInvoker.setCommand(slCommand);
-		responseCode = 200;
-		responseHeaders = Collections.EMPTY_MAP;
-		dataUrlResponse = null;
-		try {
-			commandInvoker.invoke(srcContex);
-		} catch (SLException e) {
-			log.info("Caught exception: " + e);
-			bindingProcessorError = e;
-			currentState = State.TRANSFORM;
-		}
-		if (getDataUrl() != null) {
-			log.debug("Data Url set to: " + getDataUrl());
-			currentState = State.DATAURL;
-		} else {
-			log.debug("No data url set");
-			currentState = State.TRANSFORM;
-		}
-	}
-
-	protected void handleDataUrl() {
-		log.debug("Entered State: " + State.DATAURL);
-		try {
-			DataUrl dataUrl = new DataUrl(getDataUrl());
-			DataUrlConnection conn = dataUrl.openConnection();
-
-			// set transfer headers
-			for (FormParameter fp : getTransferHeaders()) {
-				String paramString = getFormParameterAsString(fp);
-				if (paramString == null) {
-					log.error("Got empty transfer header, ignoring this");
-				} else {
-					String[] keyVal = paramString.split(":", 2);
-					String key = keyVal[0];
-					String val = null;
-					if (keyVal.length == 2) {
-						val = keyVal[1];
-						val = val.trim();
-					}  else {
-					  log.error("Invalid transfer header encoding: "+paramString);
-					  throw new SLBindingException(2005);
-					}
-					log.debug("Setting header " + key + " to value " + val);
-					conn.setHTTPHeader(key, val);
-				}
-			}
-
-			// set transfer form parameters
-			for (FormParameter fp : getTransferForms()) {
-				String contentTransferEncoding = null;
-				String contentType = fp.getFormParameterContentType();
-				String charSet = HttpUtil.getCharset(contentType, false);
-				if (charSet != null) {
-					contentType = contentType.substring(0, contentType
-							.lastIndexOf(HttpUtil.SEPERATOR[0]));
-				}
-				for (Iterator<String> header = fp.getHeaderNames(); header.hasNext();) {
-					if (HttpUtil.CONTENT_TRANSFER_ENCODING
-							.equalsIgnoreCase(header.next())) {
-						contentTransferEncoding = getFormParameterAsString(fp);
-					}
-				}
-				log.debug("Setting form: " + fp.getFormParameterName()
-						+ " contentType: " + contentType + " charset: " + charSet
-						+ " contentTransferEncoding: " + contentTransferEncoding);
-				conn.setHTTPFormParameter(fp.getFormParameterName(), fp
-						.getFormParameterValue(), contentType, charSet,
-						contentTransferEncoding);
-			}
-
-			// connect
-			conn.connect();
-			// fetch and set SL result
-			targetContext.setTargetIsDataURL(true);
-			targetContext.setTargetCertificate(conn.getServerCertificate());
-			targetContext.setTargetUrl(conn.getUrl());
-			SLResult result = commandInvoker.getResult(targetContext);
-
-			// transfer result
-			conn.transmit(result);
-
-			// process Dataurl response
-			dataUrlResponse = conn.getResponse();
-			log.debug("Received data url response code: "
-					+ dataUrlResponse.getResponseCode());
-
-			switch (dataUrlResponse.getResponseCode()) {
-			case 200:
-				String contentType = dataUrlResponse.getContentType();
-				log.debug("Got dataurl response content type: " + contentType);
-				if (contentType != null) {
-					if ((contentType.startsWith(HttpUtil.APPLICATION_URL_ENCODED))
-							|| (contentType.startsWith(HttpUtil.MULTIPART_FOTMDATA))) {
-						log.debug("Detected SL Request in dataurl response");
-						// process headers and request
-						setHTTPHeaders(dataUrlResponse.getResponseHeaders());
-						consumeRequestStream(dataUrlResponse.getStream());
-						//TODO check for bindingProcessorError
-						closeDataUrlConnection();
-						srcContex.setSourceCertificate(conn.getServerCertificate());
-						srcContex.setSourceIsDataURL(true);
-						srcContex.setSourceUrl(conn.getUrl());
-						currentState = State.PROCESS;
-					} else if (((contentType.startsWith(HttpUtil.TXT_HTML))
-							|| (contentType.startsWith(HttpUtil.TXT_PLAIN))
-              || (contentType.startsWith(HttpUtil.TXT_XML)))
-							&& (dataUrlResponse.isHttpResponseXMLOK())) {
-						log.info("Dataurl response matches <ok/> with content type: "
-								+ contentType);
-						currentState = State.TRANSFORM;
-
-					} else if ((contentType.startsWith(HttpUtil.TXT_XML))
-							&& (!dataUrlResponse.isHttpResponseXMLOK())) {
-						log
-								.debug("Detected text/xml  dataurl response with content != <ok/>");
-						headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType);
-						assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset(
-								contentType, true));
-						closeDataUrlConnection();
-						srcContex.setSourceCertificate(conn.getServerCertificate());
-						srcContex.setSourceIsDataURL(true);
-						srcContex.setSourceUrl(conn.getUrl());
-						currentState = State.PROCESS;
-						// just to be complete, actually not used
-						srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders()
-								.get(HttpUtil.HTTP_HEADER_REFERER));
-					} else {
-						resultContentType = contentType;
-						responseHeaders = dataUrlResponse.getResponseHeaders();
-						responseCode = dataUrlResponse.getResponseCode();
-						currentState = State.FINISHED;
-					}
-				} else {
-					log.debug("Content type not set in dataurl response");
-					closeDataUrlConnection();
-					throw new SLBindingException(2007);
-				}
-
-				break;
-			case 307:
-				contentType = dataUrlResponse.getContentType();
-				if ((contentType != null) && (contentType.startsWith(HttpUtil.TXT_XML))) {
-					log.debug("Received dataurl response code 307 with XML content");
-					String location = dataUrlResponse.getResponseHeaders().get(
-							HttpUtil.HTTP_HEADER_LOCATION);
-					if (location == null) {
-						log
-								.error("Did not get a location header for a 307 data url response");
-						throw new SLBindingException(2003);
-					}
-					// consumeRequestStream(dataUrlResponse.getStream());
-					FormParameterStore fp = new FormParameterStore();
-					fp.init(location.getBytes(HttpUtil.DEFAULT_CHARSET),
-							FixedFormParameters.DATAURL, null, null);
-					formParameterMap.put(FixedFormParameters.DATAURL, fp);
-					headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType);
-					assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset(
-							dataUrlResponse.getContentType(), true));
-					closeDataUrlConnection();
-					srcContex.setSourceCertificate(conn.getServerCertificate());
-					srcContex.setSourceIsDataURL(true);
-					srcContex.setSourceUrl(conn.getUrl());
-					currentState = State.PROCESS;
-					// just to be complete, actually not used
-					srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders()
-							.get(HttpUtil.HTTP_HEADER_REFERER));
-
-				} else {
-					log.debug("Received dataurl response code 307 non XML content: "
-							+ dataUrlResponse.getContentType());
-					resultContentType = dataUrlResponse.getContentType();
-					currentState = State.FINISHED;
-				}
-				responseHeaders = dataUrlResponse.getResponseHeaders();
-				responseCode = dataUrlResponse.getResponseCode();
-				break;
-
-			case 301:
-			case 302:
-			case 303:
-				responseHeaders = dataUrlResponse.getResponseHeaders();
-				responseCode = dataUrlResponse.getResponseCode();
-				resultContentType = dataUrlResponse.getContentType();
-				currentState = State.FINISHED;
-				break;
-
-			default:
-				// issue error
-				log.info("Unexpected response code from dataurl server: "
-						+ dataUrlResponse.getResponseCode());
-				throw new SLBindingException(2007);
-			}
-
-		} catch (SLException slx) {
-			bindingProcessorError = slx;
-			log.error("Error during dataurl communication");
-			resultContentType = HttpUtil.TXT_XML;
-			currentState = State.TRANSFORM;
-		} catch (SSLHandshakeException hx) {
-			bindingProcessorError = new SLException(2010);
-			log.info("Error during dataurl communication", hx);
-			resultContentType = HttpUtil.TXT_XML;
-			currentState = State.TRANSFORM;
-		} catch (IOException e) {
-			bindingProcessorError = new SLBindingException(2001);
-			log.error("Error while data url handling", e);
-			resultContentType = HttpUtil.TXT_XML;
-			currentState = State.TRANSFORM;
-			return;
-		}
-	}
-
-	protected void transformResult() {
-		log.debug("Entered State: " + State.TRANSFORM);
-		if (bindingProcessorError != null) {
-			resultContentType = HttpUtil.TXT_XML;
-		} else if (dataUrlResponse != null) {
-			resultContentType = dataUrlResponse.getContentType();
-		} else {
-			targetContext.setTargetIsDataURL(false);
-			targetContext.setTargetUrl(srcUrl);
-			try {
-				slResult = commandInvoker.getResult(targetContext);
-				resultContentType = slResult.getMimeType();
-				log
-						.debug("Successfully got SLResult from commandinvoker, setting mimetype to: "
-								+ resultContentType);
-			} catch (SLException e) {
-				log.info("Cannot get result from invoker:", e);
-				bindingProcessorError = new SLException(6002);
-				resultContentType = HttpUtil.TXT_XML;
-			}
-		}
-		templates = getTemplates(getStyleSheetUrl());
-		if (templates != null) {
-			log.debug("Output transformation required");
-			resultContentType = templates.getOutputProperties().getProperty("media-type");
-			log.debug("Got media type from stylesheet: " + resultContentType);
-			if (resultContentType == null) {
-				log.debug("Setting to default text/xml result conent type");
-				resultContentType = "text/xml";
-			}
-			log.debug("Deferring sytylesheet processing");
-		}
-		currentState = State.FINISHED;
-	}
-
-	protected void finished() {
-		log.debug("Entered State: " + State.FINISHED);
-		if (bindingProcessorError != null) {
-			log.debug("Binding processor error, sending quit command");
-			resultContentType = HttpUtil.TXT_XML;
-		}
-		sendSTALQuit();
-		log.info("Terminating Bindingprocessor; Thread: "
-				+ Thread.currentThread().getId());
-		finished = true;
-	}
-
-	// -- END Methods that handle the http binding activities as defined in the
-	// activity diagram --
-	//----------------------------------------------------------------------------
-
-	/**
-	 * Sets the headers of the SL Request. IMPORTANT: make sure to set all headers
-	 * before invoking {@link #consumeRequestStream(InputStream)}
-	 * 
-	 * @param aHeaderMap
-	 *          if null all header will be cleared.
-	 */
-	public void setHTTPHeaders(Map<String, String> aHeaderMap) {
-		headerMap = new HashMap<String, String>();
-		// ensure lowercase keys
-		if (aHeaderMap != null) {
-			for (String s : aHeaderMap.keySet()) {
-				if (s != null) {
-					headerMap.put(s.toLowerCase(), aHeaderMap.get(s));
-					if (s.equalsIgnoreCase(HttpUtil.HTTP_HEADER_REFERER)) {
-						String referer = aHeaderMap.get(s);
-						log.debug("Got referer header: " + referer);
-						srcContex.setSourceHTTPReferer(referer);
-					}
-				}
-			}
-		}
-	}
-
-	public void setSourceCertificate(X509Certificate aCert) {
-		srcContex.setSourceCertificate(aCert);
-	}
-
-	/**
-	 * The HTTPBindingProcessor does not handle redirect URLs. It only provides
-	 * the parameter.
-	 * 
-	 * @return null if redirect url is not set.
-	 */
-	public String getRedirectURL() {
-		return getFormParameterAsString(FixedFormParameters.REDIRECTURL);
-	}
-
-	public String getFormDataContentType(String aParameterName) {
-		FormParameter fp = formParameterMap.get(aParameterName);
-		if (fp != null) {
-			return fp.getFormParameterContentType();
-		}
-		return null;
-	}
-
-	public InputStream getFormData(String aParameterName) {
-		FormParameter fp = formParameterMap.get(aParameterName);
-		if (fp != null) {
-		  final String enc = fp.getHeaderValue("Content-Transfer-Encoding");
-		  if (enc == null || "binary".equals(enc)) {
-            return fp.getFormParameterValue();
-		  } else if ("base64".equals(enc)) {
-		    return new Base64InputStream(fp.getFormParameterValue());
-		  } else {
-            return new InputStream() {
-              @Override
-              public int read() throws IOException {
-                throw new IOException("Content-Transfer-Encoding : " + enc
-                    + " is not supported.");
-              }
-            };
-		  }
-		}
-		return null;
-	}
-
-	protected void assignXMLRequest(InputStream is, String charset)
-			throws IOException, SLException {
-		Reader r = new InputStreamReader(is, charset);
-		StreamSource source = new StreamSource(r);
-		SLCommandContext commandCtx = new SLCommandContext();
-		commandCtx.setSTAL(getSTAL());
-		commandCtx.setURLDereferencerContext(new SimpleFormDataContextImpl(this));
-		commandCtx.setLocale(locale);
-    slCommand = SLCommandFactory.getInstance().createSLCommand(source,
-				commandCtx);
-		log.debug("Created new command: " + slCommand);
-  }
-
-	@Override
-	public void run() {
-		boolean done = false;
-		int hopcounter = 0;
-		if (bindingProcessorError != null) {
-			currentState = State.FINISHED;
-		}
-		try {
-			while (!done) {
-				try {
-					switch (currentState) {
-					case INIT:
-						init();
-						break;
-					case PROCESS:
-						processRequest();
-						break;
-					case DATAURL:
-						handleDataUrl();
-						if (++hopcounter > config.getMaxDataUrlHops()) {
-							log.error("Maximum number of dataurl hops reached");
-							bindingProcessorError = new SLBindingException(2000);
-							currentState = State.FINISHED;
-						}
-						break;
-					case TRANSFORM:
-						transformResult();
-						break;
-					case FINISHED:
-						done = true;
-						finished();
-						break;
-					}
-				} catch (RuntimeException rte) {
-					throw rte;
-				} catch (Exception t) {
-					log.error("Caught unexpected exception", t);
-					responseCode = 200;
-					resultContentType = HttpUtil.TXT_XML;
-					responseHeaders = Collections.EMPTY_MAP;
-					bindingProcessorError = new SLException(2000);
-					currentState = State.FINISHED;
-				}
-			}
-		} catch (Throwable t) {
-			log.error("Caught unexpected exception", t);
-			responseCode = 200;
-			resultContentType = HttpUtil.TXT_XML;
-			responseHeaders = Collections.EMPTY_MAP;
-			bindingProcessorError = new SLException(2000);
-			currentState = State.FINISHED;
-		}
-		log.debug("Terminated http binding processor");
-		finished = true;
-	}
-
-	@Override
-	public void consumeRequestStream(InputStream is) {
-		try {
-			log.debug("Start consuming request stream");
-			formParameterMap.clear();
-			String cl = headerMap
-					.get(HttpUtil.HTTP_HEADER_CONTENT_TYPE.toLowerCase());
-			if (cl == null) {
-				log.info("No content type set in http header");
-				throw new SLBindingException(2006);
-			}
-			InputDecoder id = InputDecoderFactory.getDecoder(cl, is);
-			if (id == null) {
-				log.error("Cannot get inputdecoder for is");
-				throw new SLException(2006);
-			}
-			for (Iterator<FormParameter> fpi = id.getFormParameterIterator(); fpi
-					.hasNext();) {
-				FormParameter fp = fpi.next();
-				log.debug("Got request parameter with name: "
-						+ fp.getFormParameterName());
-				if (fp.getFormParameterName().equals(FixedFormParameters.XMLREQUEST)) {
-					log.debug("Creating XML Request");
-					for (Iterator<String> headerIterator = fp.getHeaderNames(); headerIterator
-							.hasNext();) {
-						String headerName = headerIterator.next();
-						if (HttpUtil.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(headerName)) {
-							String transferEncoding = fp.getHeaderValue(headerName);
-							log.debug("Got transfer encoding for xmlrequest: "
-									+ transferEncoding);
-							if (XML_REQ_TRANSFER_ENCODING.contains(transferEncoding)) {
-								log.debug("Supported transfer encoding: " + transferEncoding);
-							} else {
-								log
-										.error("Transferencoding not supported: "
-												+ transferEncoding);
-								throw new SLBindingException(2005);
-							}
-						}
-					}
-					String charset = HttpUtil.getCharset(cl, true);
-					assignXMLRequest(fp.getFormParameterValue(), charset);
-				} else {
-					FormParameterStore fps = new FormParameterStore();
-					fps.init(fp);
-					//if (!fps.isEmpty()) {
-						log.debug("Setting form parameter: " + fps.getFormParameterName());
-						formParameterMap.put(fps.getFormParameterName(), fps);
-					//}
-				}
-			}
-			if (slCommand == null) {
-				throw new SLBindingException(2004);
-			}
-		} catch (SLException slx) {
-			log.info("Error while consuming input stream " + slx);
-			bindingProcessorError = slx;
-		} catch (Throwable t) {
-			log.info("Error while consuming input stream " + t, t);
-			bindingProcessorError = new SLException(2000);
-		} finally {
-			try {
-			  if (is.read() != -1) {
-			    log.warn("Request input stream not completely read.");
-			    while (is.read() != -1);
-			  }
-			} catch (IOException e) {
-				log.error(e);
-			}
-		}
-	}
-
-	@Override
-	public String getResultContentType() {
-		return resultContentType;
-	}
-
-	protected Templates getTemplates(String styleSheetURL) {
-		if (styleSheetURL == null) {
-			log.debug("Stylesheet URL not set");
-			return null;
-		}
-		try {
-			URLDereferencerContext urlCtx = new SimpleFormDataContextImpl(this);
-			URIResolver resolver = new URIResolverAdapter(URLDereferencer
-					.getInstance(), urlCtx);
-			TransformerFactory factory = TransformerFactory.newInstance();
-			factory.setURIResolver(resolver);
-			StreamData sd = URLDereferencer.getInstance().dereference(styleSheetURL,
-					urlCtx);
-			return factory.newTemplates(new StreamSource(sd.getStream()));
-		} catch (Exception ex) {
-			log.info("Cannot instantiate transformer", ex);
-			bindingProcessorError = new SLException(2002);
-			return null;
-		}
-	}
-
-	protected void handleBindingProcessorError(OutputStream os, String encoding,
-			Templates templates) throws IOException {
-		log.debug("Writing error as result");
-		ErrorResultImpl error = new ErrorResultImpl(bindingProcessorError, locale);
-		Writer writer = writeXMLDeclarationAndProcessingInstruction(os, encoding);
-		error.writeTo(new StreamResult(writer), templates, true);
-	}
-
-	protected Writer writeXMLDeclarationAndProcessingInstruction(OutputStream os, String encoding) throws IOException {
-      if (encoding == null) {
-        encoding = HttpUtil.DEFAULT_CHARSET;
-      }
-      OutputStreamWriter writer = new OutputStreamWriter(os, encoding);
-      writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
-      writer.write("<?xml-stylesheet type=\"text/css\" href=\"errorresponse.css\"?>\n");
-      return writer;
-	}
-	
-	@Override
-	public void writeResultTo(OutputStream os, String encoding)
-			throws IOException {
-		if (encoding == null) {
-			encoding = HttpUtil.DEFAULT_CHARSET;
-		}
-		if (bindingProcessorError != null) {
-			log.debug("Detected error in binding processor, writing error as result");
-			handleBindingProcessorError(os, encoding, templates);
-			return;
-		} else if (dataUrlResponse != null) {
-			log.debug("Writing data url response  as result");
-			String charEnc = HttpUtil.getCharset(dataUrlResponse.getContentType(),
-					true);
-			InputStreamReader isr = new InputStreamReader(
-					dataUrlResponse.getStream(), charEnc);
-			OutputStreamWriter osw = new OutputStreamWriter(os, encoding);
-			if (templates == null) {
-				StreamUtil.copyStream(isr, osw);
-			} else {
-				try {
-					Transformer transformer = templates.newTransformer();
-					transformer.transform(new StreamSource(isr), new StreamResult(osw));
-				} catch (TransformerException e) {
-					log.fatal("Exception occured during result transformation", e);
-					// bindingProcessorError = new SLException(2008);
-					// handleBindingProcessorError(os, encoding, null);
-					return;
-				}
-			}
-			osw.flush();
-			isr.close();
-		} else if (slResult == null) {
-			// result not yet assigned -> must be a cancel
-			bindingProcessorError = new SLException(6001);
-			handleBindingProcessorError(os, encoding, templates);
-			return;
-		} else {
-			log.debug("Getting result from invoker");
-			boolean fragment = false;
-			Writer writer;
-			if (slResult instanceof ErrorResult) {
-			  writer = writeXMLDeclarationAndProcessingInstruction(os, encoding);
-			  fragment = true;
-			} else {
-	          writer = new OutputStreamWriter(os, encoding);
-			}
-			slResult.writeTo(new StreamResult(writer), templates, fragment);
-			writer.flush();
-		}
-	}
+public interface HTTPBindingProcessor extends BindingProcessor {
 
-	/**
-	 * The response code from the dataurl server or 200 if no dataurl server
-	 * created the result
-	 * 
-	 * @return
-	 */
-	public int getResponseCode() {
-		return responseCode;
-	}
+  public void setHTTPHeaders(Map<String, String> headerMap);
+  
+  public InputStream getFormData(String parameterName);
 
-	/**
-	 * All headers from the data url server in case of a direct forward from the
-	 * dataurl server.
-	 * 
-	 * @return
-	 */
-	public Map<String, String> getResponseHeaders() {
-		return responseHeaders;
-	}
+  public String getRedirectURL();
 
-	@Override
-	public void setLocale(Locale locale) {
-		if (locale == null) {
-			throw new NullPointerException("Locale must not be set to null");
-		}
-		this.locale = locale;
-	}
+  public int getResponseCode();
 
-	@Override
-  public boolean isFinished() {
-    return finished;
-  }
-}
\ No newline at end of file
+  public Map<String, String> getResponseHeaders();
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorFactory.java
new file mode 100644
index 00000000..41688e9b
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorFactory.java
@@ -0,0 +1,80 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.binding;
+
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSocketFactory;
+
+
+import at.gv.egiz.bku.utils.binding.Protocol;
+
+public class HTTPBindingProcessorFactory extends AbstractBindingProcessorFactory implements BindingProcessorFactory {
+  
+  private HostnameVerifier hostnameVerifier;
+  
+  private SSLSocketFactory sslSocketFactory;
+  
+  public HTTPBindingProcessorFactory() {
+    Set<Protocol> sp = new HashSet<Protocol>();
+    Collections.addAll(sp, Protocol.HTTP, Protocol.HTTPS);
+    supportedProtocols = Collections.unmodifiableSet(sp);
+  }
+  
+  /**
+   * @return the hostnameVerifier
+   */
+  public HostnameVerifier getHostnameVerifier() {
+    return hostnameVerifier;
+  }
+
+  /**
+   * @param hostnameVerifier the hostnameVerifier to set
+   */
+  public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
+    this.hostnameVerifier = hostnameVerifier;
+  }
+
+  /**
+   * @return the sslSocketFactory
+   */
+  public SSLSocketFactory getSslSocketFactory() {
+    return sslSocketFactory;
+  }
+
+  /**
+   * @param sslSocketFactory the sslSocketFactory to set
+   */
+  public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) {
+    this.sslSocketFactory = sslSocketFactory;
+  }
+
+  @Override
+  public BindingProcessor createBindingProcessor() {
+    HTTPBindingProcessorImpl httpBindingProcessor = new HTTPBindingProcessorImpl();
+    configureBindingProcessor(httpBindingProcessor);
+    httpBindingProcessor.setHostnameVerifier(hostnameVerifier);
+    httpBindingProcessor.setSslSocketFactory(sslSocketFactory);
+    return httpBindingProcessor;
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorImpl.java
new file mode 100644
index 00000000..b5f34689
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorImpl.java
@@ -0,0 +1,896 @@
+/*
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.gv.egiz.bku.binding;
+
+import iaik.utils.Base64InputStream;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.net.URL;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLSocketFactory;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.bku.conf.MoccaConfigurationFacade;
+import at.gv.egiz.bku.slcommands.ErrorResult;
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slcommands.SLCommandContext;
+import at.gv.egiz.bku.slcommands.SLResult;
+import at.gv.egiz.bku.slcommands.SLSourceContext;
+import at.gv.egiz.bku.slcommands.SLTargetContext;
+import at.gv.egiz.bku.slcommands.impl.ErrorResultImpl;
+import at.gv.egiz.bku.slexceptions.SLBindingException;
+import at.gv.egiz.bku.slexceptions.SLException;
+import at.gv.egiz.bku.spring.ConfigurationFactoryBean;
+import at.gv.egiz.bku.utils.StreamUtil;
+import at.gv.egiz.bku.utils.urldereferencer.StreamData;
+import at.gv.egiz.bku.utils.urldereferencer.URIResolverAdapter;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
+import at.gv.egiz.stal.QuitRequest;
+import at.gv.egiz.stal.STALRequest;
+
+/**
+ * Class performing the HTTP binding as defined by the CCE specification.
+ * Currently a huge monolithic class.
+ * 
+ * @TODO refactor
+ */
+@SuppressWarnings("unchecked")
+public class HTTPBindingProcessorImpl extends AbstractBindingProcessor implements
+		HTTPBindingProcessor, FormDataURLSupplier {
+
+	private final Logger log = LoggerFactory.getLogger(HTTPBindingProcessorImpl.class);
+
+	private static enum State {
+		INIT, PROCESS, DATAURL, TRANSFORM, FINISHED
+	};
+
+	public final static Collection<String> XML_REQ_TRANSFER_ENCODING = Arrays
+			.asList(new String[] { "binary" });
+
+	protected static String XML_MIME_TYPE = "text/xml";
+	protected static String BINARY_MIME_TYPE = "application/octet-stream";
+
+  /**
+   * The citizen card environment identifier for <code>Server</code> and
+   * <code>UserAgent</code> headers.
+   */
+  protected static String CITIZENC_CARD_ENVIRONMENT = "citizen-card-environment/1.2";
+	
+  /**
+   * The configuration facade used to access the MOCCA configuration.
+   */
+  protected ConfigurationFacade configurationFacade = new ConfigurationFacade();
+
+  public class ConfigurationFacade implements MoccaConfigurationFacade {
+    
+    public static final String DATAURLCLIENT_MAXHOPS = "DataURLConnection.MaxHops";
+
+    public int getMaxDataUrlHops() {
+      return configuration.getInt(DATAURLCLIENT_MAXHOPS, 10);
+    }
+
+    public String getProductName() {
+      return configuration.getString(
+          ConfigurationFactoryBean.MOCCA_IMPLEMENTATIONNAME_PROPERTY, "MOCCA");
+    }
+    
+    public String getProductVersion() {
+      return configuration.getString(
+          ConfigurationFactoryBean.MOCCA_IMPLEMENTATIONVERSION_PROPERTY,
+          "UNKNOWN");
+    }
+    
+    public String getSignatureLayout() {
+      return configuration
+          .getString(ConfigurationFactoryBean.SIGNATURE_LAYOUT_PROPERTY);
+    }
+    
+  }  
+	
+	/**
+	 * If null everything is ok and the result is taken from the command invoker.
+	 */
+	protected SLException bindingProcessorError;
+	protected SSLSocketFactory sslSocketFactory;
+	protected HostnameVerifier hostnameVerifier;
+	protected DataUrlResponse dataUrlResponse;
+	protected Map<String, String> headerMap = Collections.EMPTY_MAP;
+	protected SLCommand slCommand;
+	protected Map<String, FormParameter> formParameterMap = new HashMap<String, FormParameter>();
+	protected SLSourceContext srcContex = new SLSourceContext();
+	protected SLTargetContext targetContext = new SLTargetContext();
+	protected URL srcUrl;
+	protected State currentState = State.INIT;
+	protected Templates templates = null;
+	protected String resultContentType = null;
+	protected SLResult slResult = null;
+	protected int responseCode = 200;
+	protected Map<String, String> responseHeaders = Collections.EMPTY_MAP;
+	protected boolean finished = false;
+
+    @Override
+    public void setUrlDereferencer(URLDereferencer urlDereferencer) {
+      super.setUrlDereferencer(new FormDataURLDereferencer(urlDereferencer, this));
+    }
+
+    /**
+     * @return the sslSocketFactory
+     */
+    public SSLSocketFactory getSslSocketFactory() {
+      return sslSocketFactory;
+    }
+  
+    /**
+     * @param sslSocketFactory
+     *          the sslSocketFactory to set
+     */
+    public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) {
+      this.sslSocketFactory = sslSocketFactory;
+    }
+  
+    /**
+     * @return the hostnameVerifier
+     */
+    public HostnameVerifier getHostnameVerifier() {
+      return hostnameVerifier;
+    }
+  
+    /**
+     * @param hostnameVerifier
+     *          the hostnameVerifier to set
+     */
+    public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
+      this.hostnameVerifier = hostnameVerifier;
+    }
+	
+    protected void sendSTALQuit() {
+		log.debug("Sending QUIT command to STAL.");
+		List<STALRequest> quit = new ArrayList<STALRequest>(1);
+		quit.add(new QuitRequest());
+		getSTAL().handleRequest(quit);
+	}
+
+	protected String getFormParameterAsString(String formParameterName) {
+		FormParameter fp = formParameterMap.get(formParameterName);
+		return getFormParameterAsString(fp);
+	}
+
+	protected String getFormParameterAsString(FormParameter fp) {
+		if (fp == null) {
+			return null;
+		}
+		try {
+			return StreamUtil.asString(fp.getFormParameterValue(), HttpUtil
+					.getCharset(fp.getFormParameterContentType(), true));
+		} catch (IOException e) {
+			return null;
+		}
+	}
+
+	protected String getDataUrl() {
+		return getFormParameterAsString(FixedFormParameters.DATAURL);
+	}
+
+	protected String getStyleSheetUrl() {
+		return getFormParameterAsString(FixedFormParameters.STYLESHEETURL);
+	}
+
+	protected List<FormParameter> getFormParameters(String parameterNamePostfix) {
+		List<FormParameter> resultList = new ArrayList<FormParameter>();
+		for (Iterator<String> fpi = formParameterMap.keySet().iterator(); fpi
+				.hasNext();) {
+			String paramName = fpi.next();
+			if (paramName.endsWith(parameterNamePostfix)) {
+				resultList.add(formParameterMap.get(paramName));
+			}
+		}
+		return resultList;
+	}
+
+	protected List<FormParameter> getTransferHeaders() {
+		return getFormParameters("__");
+	}
+
+	protected List<FormParameter> getTransferForms() {
+		List<FormParameter> resultList = new ArrayList<FormParameter>();
+		for (Iterator<String> fpi = formParameterMap.keySet().iterator(); fpi
+				.hasNext();) {
+			String paramName = fpi.next();
+			if ((paramName.endsWith("_")) && (!paramName.endsWith("__"))) {
+				resultList.add(formParameterMap.get(paramName));
+			}
+		}
+		return resultList;
+	}
+
+	protected void closeDataUrlConnection() {
+		log.debug("Closing data url input stream.");
+		if (dataUrlResponse == null) {
+			return;
+		}
+		InputStream is = dataUrlResponse.getStream();
+		if (is != null) {
+			try {
+				is.close();
+			} catch (IOException e) {
+				log.info("Error closing input stream to dataurl server.", e);
+			}
+		}
+	}
+
+	//----------------------------------------------------------------------------
+	// ----------- END CONVENIENCE METHODS -----------
+
+	//----------------------------------------------------------------------------
+	// -- BEGIN Methods that handle the http binding activities as defined in the
+	// activity diagram --
+
+	protected void init() {
+		log.info("Starting Bindingprocessor : {}.", id);
+		if (bindingProcessorError != null) {
+			log.debug("Detected binding processor error, sending quit command.");
+			currentState = State.FINISHED;
+		} else if (slCommand == null) {
+			log.error("SLCommand not set. (consumeRequest not called?)");
+			bindingProcessorError = new SLException(2000);
+			currentState = State.FINISHED;
+		} else {
+			currentState = State.PROCESS;
+		}
+	}
+
+	protected void processRequest() {
+		log.info("Entered State: {}, Processing {}.", State.PROCESS, slCommand.getName());
+        SLCommandContext commandCtx = new SLCommandContext(
+            getSTAL(),
+            new FormDataURLDereferencer(urlDereferencer, this), 
+            locale);
+		commandInvoker.setCommand(commandCtx, slCommand);
+		responseCode = 200;
+		responseHeaders = Collections.EMPTY_MAP;
+		dataUrlResponse = null;
+		try {
+			commandInvoker.invoke(srcContex);
+		} catch (SLException e) {
+			log.info("Failed to invoke command.", e);
+			bindingProcessorError = e;
+			currentState = State.TRANSFORM;
+		}
+		if (getDataUrl() != null) {
+			log.debug("DataUrl set to: {}.", getDataUrl());
+			currentState = State.DATAURL;
+		} else {
+			log.debug("No data url set.");
+			currentState = State.TRANSFORM;
+		}
+	}
+
+	protected void handleDataUrl() {
+		log.info("Entered State: {}, DataURL={}.", State.DATAURL, getDataUrl());
+		try {
+			DataUrl dataUrl = new DataUrl(getDataUrl());
+			HttpsDataURLConnection conn = (HttpsDataURLConnection) dataUrl.openConnection();
+			
+			// set user agent and signature layout headers
+			conn.setHTTPHeader(HttpUtil.HTTP_HEADER_USER_AGENT, getServerHeaderValue());
+			conn.setHTTPHeader(HttpUtil.HTTP_HEADER_SIGNATURE_LAYOUT, getSignatureLayoutHeaderValue());
+			conn.setHostnameVerifier(hostnameVerifier);
+			conn.setSSLSocketFactory(sslSocketFactory);
+
+			// set transfer headers
+			for (FormParameter fp : getTransferHeaders()) {
+				String paramString = getFormParameterAsString(fp);
+				if (paramString == null) {
+					log.error("Got empty transfer header, ignoring this.");
+				} else {
+					String[] keyVal = paramString.split(":", 2);
+					String key = keyVal[0];
+					String val = null;
+					if (keyVal.length == 2) {
+						val = keyVal[1];
+						val = val.trim();
+					}  else {
+					  log.error("Invalid transfer header encoding: {}.", paramString);
+					  throw new SLBindingException(2005);
+					}
+					log.debug("Setting header '{}' to value '{}'.", key, val);
+					conn.setHTTPHeader(key, val);
+				}
+			}
+
+			// set transfer form parameters
+			for (FormParameter fp : getTransferForms()) {
+				String contentTransferEncoding = null;
+				String contentType = fp.getFormParameterContentType();
+				String charSet = HttpUtil.getCharset(contentType, false);
+				if (charSet != null) {
+					contentType = contentType.substring(0, contentType
+							.lastIndexOf(HttpUtil.SEPERATOR[0]));
+				}
+				for (Iterator<String> header = fp.getHeaderNames(); header.hasNext();) {
+					if (HttpUtil.CONTENT_TRANSFER_ENCODING
+							.equalsIgnoreCase(header.next())) {
+						contentTransferEncoding = getFormParameterAsString(fp);
+					}
+				}
+				if (log.isDebugEnabled()) {
+				  Object[] args = {fp.getFormParameterName(), contentType, contentTransferEncoding};
+				  log.debug("Setting form parameter '{}'" +
+				  		" (content-type {}, charset {}, content transfer encoding {})", args);
+				}
+				conn.setHTTPFormParameter(fp.getFormParameterName(), fp
+						.getFormParameterValue(), contentType, charSet,
+						contentTransferEncoding);
+			}
+
+			// connect
+			conn.connect();
+			// fetch and set SL result
+			targetContext.setTargetIsDataURL(true);
+			X509Certificate serverCertificate = null;
+			if (conn.getServerCertificates() instanceof X509Certificate[]) {
+			  serverCertificate = (X509Certificate) conn.getServerCertificates()[0];
+			}
+            targetContext.setTargetCertificate(serverCertificate);
+			targetContext.setTargetUrl(conn.getURL());
+			SLResult result = commandInvoker.getResult(targetContext);
+
+			// transfer result
+			conn.transmit(result);
+
+			// process Dataurl response
+			dataUrlResponse = conn.getResponse();
+			log.debug("Received data url response code: {}.", dataUrlResponse.getResponseCode());
+
+			switch (dataUrlResponse.getResponseCode()) {
+			case 200:
+				String contentType = dataUrlResponse.getContentType();
+				log.debug("Got dataurl response content type: {}.", contentType);
+				if (contentType != null) {
+					if ((contentType.startsWith(HttpUtil.APPLICATION_URL_ENCODED))
+							|| (contentType.startsWith(HttpUtil.MULTIPART_FOTMDATA))) {
+						log.debug("Detected SL Request in dataurl response.");
+						// process headers and request
+						setHTTPHeaders(dataUrlResponse.getResponseHeaders());
+						consumeRequestStream(dataUrlResponse.getUrl(), dataUrlResponse.getStream());
+						//TODO check for bindingProcessorError
+						closeDataUrlConnection();
+						srcContex.setSourceCertificate(serverCertificate);
+						srcContex.setSourceIsDataURL(true);
+						srcContex.setSourceUrl(conn.getURL());
+						currentState = State.PROCESS;
+					} else if (((contentType.startsWith(HttpUtil.TXT_HTML))
+							|| (contentType.startsWith(HttpUtil.TXT_PLAIN))
+              || (contentType.startsWith(HttpUtil.TXT_XML)))
+							&& (dataUrlResponse.isHttpResponseXMLOK())) {
+						log.info("Dataurl response matches <ok/> with content type: {}.", contentType);
+						currentState = State.TRANSFORM;
+
+					} else if ((contentType.startsWith(HttpUtil.TXT_XML))
+							&& (!dataUrlResponse.isHttpResponseXMLOK())) {
+						log.debug("Detected text/xml  dataurl response with content != <ok/>");
+						headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType);
+						assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset(
+								contentType, true));
+						closeDataUrlConnection();
+						srcContex.setSourceCertificate(serverCertificate);
+						srcContex.setSourceIsDataURL(true);
+						srcContex.setSourceUrl(conn.getURL());
+						currentState = State.PROCESS;
+						// just to be complete, actually not used
+						srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders()
+								.get(HttpUtil.HTTP_HEADER_REFERER));
+					} else {
+						resultContentType = contentType;
+						responseHeaders = dataUrlResponse.getResponseHeaders();
+						responseCode = dataUrlResponse.getResponseCode();
+						currentState = State.FINISHED;
+					}
+				} else {
+					log.debug("Content type not set in dataurl response.");
+					closeDataUrlConnection();
+					throw new SLBindingException(2007);
+				}
+
+				break;
+			case 307:
+				contentType = dataUrlResponse.getContentType();
+				if ((contentType != null) && (contentType.startsWith(HttpUtil.TXT_XML))) {
+					log.debug("Received dataurl response code 307 with XML content.");
+					String location = dataUrlResponse.getResponseHeaders().get(
+							HttpUtil.HTTP_HEADER_LOCATION);
+					if (location == null) {
+						log.error("Did not get a location header for a 307 data url response.");
+						throw new SLBindingException(2003);
+					}
+					// consumeRequestStream(dataUrlResponse.getStream());
+					FormParameterStore fp = new FormParameterStore();
+					fp.init(location.getBytes(HttpUtil.DEFAULT_CHARSET),
+							FixedFormParameters.DATAURL, null, null);
+					formParameterMap.put(FixedFormParameters.DATAURL, fp);
+					headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType);
+					assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset(
+							dataUrlResponse.getContentType(), true));
+					closeDataUrlConnection();
+					srcContex.setSourceCertificate(serverCertificate);
+					srcContex.setSourceIsDataURL(true);
+					srcContex.setSourceUrl(conn.getURL());
+					currentState = State.PROCESS;
+					// just to be complete, actually not used
+					srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders()
+							.get(HttpUtil.HTTP_HEADER_REFERER));
+
+				} else {
+					log.debug("Received dataurl response code 307 non XML content: {}.", 
+					    dataUrlResponse.getContentType());
+					resultContentType = dataUrlResponse.getContentType();
+					currentState = State.FINISHED;
+				}
+				responseHeaders = dataUrlResponse.getResponseHeaders();
+				responseCode = dataUrlResponse.getResponseCode();
+				break;
+
+			case 301:
+			case 302:
+			case 303:
+				responseHeaders = dataUrlResponse.getResponseHeaders();
+				responseCode = dataUrlResponse.getResponseCode();
+				resultContentType = dataUrlResponse.getContentType();
+				currentState = State.FINISHED;
+				break;
+
+			default:
+				// issue error
+				log.info("Unexpected response code from dataurl server: {}.", 
+				    dataUrlResponse.getResponseCode());
+				throw new SLBindingException(2007);
+			}
+
+		} catch (SLException slx) {
+			bindingProcessorError = slx;
+			log.error("Error during dataurl communication.");
+			resultContentType = HttpUtil.TXT_XML;
+			currentState = State.TRANSFORM;
+		} catch (SSLHandshakeException hx) {
+			bindingProcessorError = new SLException(2010);
+			log.info("Error during dataurl communication.", hx);
+			resultContentType = HttpUtil.TXT_XML;
+			currentState = State.TRANSFORM;
+		} catch (IOException e) {
+			bindingProcessorError = new SLBindingException(2001);
+			log.error("Error while data url handling", e);
+			resultContentType = HttpUtil.TXT_XML;
+			currentState = State.TRANSFORM;
+			return;
+		}
+	}
+
+	protected void transformResult() {
+		log.info("Entered State: {}.", State.TRANSFORM);
+		if (bindingProcessorError != null) {
+			resultContentType = HttpUtil.TXT_XML;
+		} else if (dataUrlResponse != null) {
+			resultContentType = dataUrlResponse.getContentType();
+		} else {
+			targetContext.setTargetIsDataURL(false);
+			targetContext.setTargetUrl(srcUrl);
+			try {
+				slResult = commandInvoker.getResult(targetContext);
+				resultContentType = slResult.getMimeType();
+				log.debug("Successfully got SLResult from commandinvoker, setting mimetype to: {}.",
+								resultContentType);
+			} catch (SLException e) {
+				log.info("Cannot get result from invoker:", e);
+				bindingProcessorError = new SLException(6002);
+				resultContentType = HttpUtil.TXT_XML;
+			}
+		}
+		templates = getTemplates(getStyleSheetUrl());
+		if (templates != null) {
+			log.debug("Output transformation required.");
+			resultContentType = templates.getOutputProperties().getProperty("media-type");
+			log.debug("Got media type from stylesheet: {}.", resultContentType);
+			if (resultContentType == null) {
+				log.debug("Setting to default text/xml result conent type.");
+				resultContentType = "text/xml";
+			}
+			log.debug("Deferring sytylesheet processing.");
+		}
+		currentState = State.FINISHED;
+	}
+
+	protected void finished() {
+		log.info("Entered State: {}.", State.FINISHED);
+		if (bindingProcessorError != null) {
+			log.debug("Binding processor error, sending quit command.");
+			resultContentType = HttpUtil.TXT_XML;
+		}
+		sendSTALQuit();
+		log.info("Terminating Bindingprocessor : {}.", id);
+		finished = true;
+	}
+
+	// -- END Methods that handle the http binding activities as defined in the
+	// activity diagram --
+	//----------------------------------------------------------------------------
+
+    public String getServerHeaderValue() {
+      return CITIZENC_CARD_ENVIRONMENT + " "
+          + configurationFacade.getProductName() + "/"
+          + configurationFacade.getProductVersion();
+    }
+
+    public String getSignatureLayoutHeaderValue() {
+      return configurationFacade.getSignatureLayout();
+    }
+	
+	/**
+	 * Sets the headers of the SL Request. IMPORTANT: make sure to set all headers
+	 * before invoking {@link #consumeRequestStream(String, InputStream)}
+	 * 
+	 * @param aHeaderMap
+	 *          if null all header will be cleared.
+	 */
+    @Override
+	public void setHTTPHeaders(Map<String, String> aHeaderMap) {
+		headerMap = new HashMap<String, String>();
+		// ensure lowercase keys
+		if (aHeaderMap != null) {
+			for (String s : aHeaderMap.keySet()) {
+				if (s != null) {
+					headerMap.put(s.toLowerCase(), aHeaderMap.get(s));
+					if (s.equalsIgnoreCase(HttpUtil.HTTP_HEADER_REFERER)) {
+						String referer = aHeaderMap.get(s);
+						log.debug("Got referer header: {}.", referer);
+						srcContex.setSourceHTTPReferer(referer);
+					}
+				}
+			}
+		}
+	}
+
+	public void setSourceCertificate(X509Certificate aCert) {
+		srcContex.setSourceCertificate(aCert);
+	}
+
+	/**
+	 * The HTTPBindingProcessor does not handle redirect URLs. It only provides
+	 * the parameter.
+	 * 
+	 * @return null if redirect url is not set.
+	 */
+	public String getRedirectURL() {
+		return getFormParameterAsString(FixedFormParameters.REDIRECTURL);
+	}
+
+	public String getFormDataContentType(String aParameterName) {
+		FormParameter fp = formParameterMap.get(aParameterName);
+		if (fp != null) {
+			return fp.getFormParameterContentType();
+		}
+		return null;
+	}
+
+	public InputStream getFormData(String aParameterName) {
+		FormParameter fp = formParameterMap.get(aParameterName);
+		if (fp != null) {
+		  final String enc = fp.getHeaderValue("Content-Transfer-Encoding");
+		  if (enc == null || "binary".equals(enc)) {
+            return fp.getFormParameterValue();
+		  } else if ("base64".equals(enc)) {
+		    return new Base64InputStream(fp.getFormParameterValue());
+		  } else {
+            return new InputStream() {
+              @Override
+              public int read() throws IOException {
+                throw new IOException("Content-Transfer-Encoding : " + enc
+                    + " is not supported.");
+              }
+            };
+		  }
+		}
+		return null;
+	}
+
+	protected void assignXMLRequest(InputStream is, String charset)
+			throws IOException, SLException {
+		Reader r = new InputStreamReader(is, charset);
+		StreamSource source = new StreamSource(r);
+        slCommand = slCommandFactory.createSLCommand(source);
+        log.info("XMLRequest={}. Created new command: {}.", slCommand.getName(), slCommand
+            .getClass().getName());
+  }
+
+	@Override
+	public void process() {
+		boolean done = false;
+		int hopcounter = 0;
+		if (bindingProcessorError != null) {
+			currentState = State.FINISHED;
+		}
+		try {
+			while (!done) {
+				try {
+					switch (currentState) {
+					case INIT:
+						init();
+						break;
+					case PROCESS:
+						processRequest();
+						break;
+					case DATAURL:
+						handleDataUrl();
+						if (++hopcounter > configurationFacade.getMaxDataUrlHops()) {
+							log.error("Maximum number ({}) of dataurl hops reached.", 
+							    configurationFacade.getMaxDataUrlHops());
+							bindingProcessorError = new SLBindingException(2000);
+							currentState = State.FINISHED;
+						}
+						break;
+					case TRANSFORM:
+						transformResult();
+						break;
+					case FINISHED:
+						done = true;
+						finished();
+						break;
+					}
+				} catch (RuntimeException rte) {
+					throw rte;
+				} catch (Exception e) {
+					log.error("Caught unexpected exception.", e);
+					responseCode = 200;
+					resultContentType = HttpUtil.TXT_XML;
+					responseHeaders = Collections.EMPTY_MAP;
+					bindingProcessorError = new SLException(2000);
+					currentState = State.FINISHED;
+				}
+			}
+		} catch (Throwable t) {
+			log.error("Caught unexpected exception.", t);
+			responseCode = 200;
+			resultContentType = HttpUtil.TXT_XML;
+			responseHeaders = Collections.EMPTY_MAP;
+			bindingProcessorError = new SLException(2000);
+			currentState = State.FINISHED;
+		}
+		log.debug("Terminated http binding processor.");
+		finished = true;
+	}
+
+	@Override
+	public void consumeRequestStream(String url, InputStream is) {
+		try {
+          this.srcUrl = new URL(url);
+          srcContex.setSourceUrl(srcUrl);
+	        srcContex.setSourceIsDataURL(false);
+			log.debug("Start consuming request stream.");
+			formParameterMap.clear();
+			String ct = headerMap
+					.get(HttpUtil.HTTP_HEADER_CONTENT_TYPE.toLowerCase());
+			if (ct == null) {
+				log.info("No content type set in http header.");
+				throw new SLBindingException(2006);
+			}
+			InputDecoder id = InputDecoderFactory.getDecoder(ct, is);
+			if (id == null) {
+				log.error("Cannot get inputdecoder for content type {}.", ct);
+				throw new SLException(2006);
+			}
+			for (Iterator<FormParameter> fpi = id.getFormParameterIterator(); fpi
+					.hasNext();) {
+				FormParameter fp = fpi.next();
+				log.debug("Got request parameter with name: {}.", fp.getFormParameterName());
+				if (fp.getFormParameterName().equals(FixedFormParameters.XMLREQUEST)) {
+					log.debug("Creating XML Request.");
+					for (Iterator<String> headerIterator = fp.getHeaderNames(); headerIterator
+							.hasNext();) {
+						String headerName = headerIterator.next();
+						if (HttpUtil.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(headerName)) {
+							String transferEncoding = fp.getHeaderValue(headerName);
+							log.debug("Got transfer encoding for xmlrequest: {}.",
+									transferEncoding);
+							if (XML_REQ_TRANSFER_ENCODING.contains(transferEncoding)) {
+								log.debug("Supported transfer encoding: {}.", transferEncoding);
+							} else {
+								log.error("Transfer encoding '{}' not supported.", transferEncoding);
+								throw new SLBindingException(2005);
+							}
+						}
+					}
+					String charset = HttpUtil.getCharset(ct, true);
+					assignXMLRequest(fp.getFormParameterValue(), charset);
+				} else {
+					FormParameterStore fps = new FormParameterStore();
+					fps.init(fp);
+					//if (!fps.isEmpty()) {
+						log.debug("Setting form parameter: {}.", fps.getFormParameterName());
+						formParameterMap.put(fps.getFormParameterName(), fps);
+					//}
+				}
+			}
+			if (slCommand == null) {
+				throw new SLBindingException(2004);
+			}
+		} catch (SLException slx) {
+			log.info("Error while consuming input stream.", slx);
+			bindingProcessorError = slx;
+		} catch (Throwable t) {
+			log.info("Error while consuming input stream.", t);
+			bindingProcessorError = new SLException(2000);
+		} finally {
+			try {
+			  if (is.read() != -1) {
+			    log.warn("Request input stream not completely read.");
+			    while (is.read() != -1);
+			  }
+			  log.debug("Finished consuming request stream.");
+			} catch (IOException e) {
+				log.error("Failed to read request input stream.", e);
+			}
+		}
+	}
+
+	@Override
+	public String getResultContentType() {
+		return resultContentType;
+	}
+
+	protected Templates getTemplates(String styleSheetURL) {
+		if (styleSheetURL == null) {
+			log.debug("Stylesheet URL not set.");
+			return null;
+		}
+		try {
+			TransformerFactory factory = TransformerFactory.newInstance();
+			factory.setURIResolver(new URIResolverAdapter(urlDereferencer));
+			StreamData sd = urlDereferencer.dereference(styleSheetURL);
+			return factory.newTemplates(new StreamSource(sd.getStream()));
+		} catch (Exception ex) {
+			log.info("Cannot instantiate transformer.", ex);
+			bindingProcessorError = new SLException(2002);
+			return null;
+		}
+	}
+
+	protected void handleBindingProcessorError(OutputStream os, String encoding,
+			Templates templates) throws IOException {
+		log.debug("Writing error as result.");
+		ErrorResultImpl error = new ErrorResultImpl(bindingProcessorError, locale);
+		Writer writer = writeXMLDeclarationAndProcessingInstruction(os, encoding);
+		error.writeTo(new StreamResult(writer), templates, true);
+	}
+
+	protected Writer writeXMLDeclarationAndProcessingInstruction(OutputStream os, String encoding) throws IOException {
+      if (encoding == null) {
+        encoding = HttpUtil.DEFAULT_CHARSET;
+      }
+      OutputStreamWriter writer = new OutputStreamWriter(os, encoding);
+      writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
+      writer.write("<?xml-stylesheet type=\"text/css\" href=\"errorresponse.css\"?>\n");
+      return writer;
+	}
+	
+	@Override
+	public void writeResultTo(OutputStream os, String encoding)
+			throws IOException {
+		if (encoding == null) {
+			encoding = HttpUtil.DEFAULT_CHARSET;
+		}
+		if (bindingProcessorError != null) {
+			log.debug("Detected error in binding processor, writing error as result.");
+			handleBindingProcessorError(os, encoding, templates);
+			return;
+		} else if (dataUrlResponse != null) {
+			log.debug("Writing data url response as result.");
+			String charEnc = HttpUtil.getCharset(dataUrlResponse.getContentType(),
+					true);
+			InputStreamReader isr = new InputStreamReader(
+					dataUrlResponse.getStream(), charEnc);
+			OutputStreamWriter osw = new OutputStreamWriter(os, encoding);
+			if (templates == null) {
+				StreamUtil.copyStream(isr, osw);
+			} else {
+				try {
+					Transformer transformer = templates.newTransformer();
+					transformer.transform(new StreamSource(isr), new StreamResult(osw));
+				} catch (TransformerException e) {
+					log.error("Exception occured during result transformation.", e);
+					// bindingProcessorError = new SLException(2008);
+					// handleBindingProcessorError(os, encoding, null);
+					return;
+				}
+			}
+			osw.flush();
+			isr.close();
+		} else if (slResult == null) {
+			// result not yet assigned -> must be a cancel
+			bindingProcessorError = new SLException(6001);
+			handleBindingProcessorError(os, encoding, templates);
+			return;
+		} else {
+			log.debug("Getting result from invoker.");
+			boolean fragment = false;
+			Writer writer;
+			if (slResult instanceof ErrorResult) {
+			  writer = writeXMLDeclarationAndProcessingInstruction(os, encoding);
+			  fragment = true;
+			} else {
+	          writer = new OutputStreamWriter(os, encoding);
+			}
+			slResult.writeTo(new StreamResult(writer), templates, fragment);
+			writer.flush();
+		}
+	}
+
+	/**
+	 * The response code from the dataurl server or 200 if no dataurl server
+	 * created the result
+	 * 
+	 * @return
+	 */
+	@Override
+	public int getResponseCode() {
+		return responseCode;
+	}
+
+	/**
+	 * All headers from the data url server in case of a direct forward from the
+	 * dataurl server.
+	 * 
+	 * @return
+	 */
+	@Override
+	public Map<String, String> getResponseHeaders() {
+	  LinkedHashMap<String, String> headers = new LinkedHashMap<String, String>();
+	  headers.put(HttpUtil.HTTP_HEADER_SERVER, getServerHeaderValue());
+	  headers.put(HttpUtil.HTTP_HEADER_SIGNATURE_LAYOUT, getSignatureLayoutHeaderValue());
+	  headers.putAll(responseHeaders);
+	  return headers;
+	}
+
+  public boolean isFinished() {
+    return finished;
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpDataURLConnection.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpDataURLConnection.java
new file mode 100644
index 00000000..d4ee55d2
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpDataURLConnection.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2009 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package at.gv.egiz.bku.binding;
+
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * A HTTP DataURLConnection.
+ * 
+ * @author mcentner
+ */
+public abstract class HttpDataURLConnection extends DataUrlConnection {
+
+  /**
+   * Constructs a DataURL connection to the specified URL.
+   * 
+   * @param url
+   *          the URL to send responses and retrieve any further requests
+   */
+  public HttpDataURLConnection(URL url) {
+    super(url);
+  }
+
+  /**
+   * Set a HTTP header.
+   * 
+   * @param key
+   *          the key
+   * @param value
+   *          multiple values are assumed to have the correct formatting
+   *          (comma-separated list)
+   */
+  public abstract void setHTTPHeader(String key, String value);
+
+  /**
+   * Set a HTTP form parameter to be transmitted with the SLResult.
+   * 
+   * @param name
+   *          the name of the form parameter
+   * @param data
+   *          the content of the form parameter
+   * @param contentType
+   *          the content type (may be <code>null</code>)
+   * @param charSet
+   *          the character set (may be <code>null</code>)
+   * @param transferEncoding
+   *          the transfer encoding (may be <code>null</code>)
+   */
+  public abstract void setHTTPFormParameter(String name, InputStream data,
+      String contentType, String charSet, String transferEncoding);
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpUtil.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpUtil.java
index 5ea7b25e..8282e34e 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpUtil.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpUtil.java
@@ -31,7 +31,8 @@ public class HttpUtil {
   public final static String HTTP_HEADER_CONTENT_TYPE = "Content-Type";
   public static final String HTTP_HEADER_USER_AGENT = "User-Agent";
   public static final String HTTP_HEADER_SERVER = "Server";
-  public final static String HTTP_HEADER_REFERER = "Referer";
+  public final static String HTTP_HEADER_REFERER = "Referer";
+  public static final String HTTP_HEADER_SIGNATURE_LAYOUT = "SignatureLayout";
   public final static String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
   public final static String MULTIPART_FOTMDATA = "multipart/form-data";
   public final static String MULTIPART_FOTMDATA_BOUNDARY = "boundary";
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpsDataURLConnection.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpsDataURLConnection.java
new file mode 100644
index 00000000..0054d52c
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpsDataURLConnection.java
@@ -0,0 +1,72 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.binding;
+
+import java.io.IOException;
+import java.net.URL;
+import java.security.cert.Certificate;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSocketFactory;
+
+public abstract class HttpsDataURLConnection extends HttpDataURLConnection {
+  
+  /**
+   * Construct a new 
+   * 
+   * @param url
+   * @throws IOException 
+   */
+  public HttpsDataURLConnection(URL url) {
+    super(url);
+  }
+
+  /**
+   * Sets the <code>SSLSocketFactory</code> to be used when this instance
+   * creates sockets for secure https URL connections.
+   * 
+   * @param socketFactory
+   *          the SSL socket factory
+   */
+  public abstract void setSSLSocketFactory(SSLSocketFactory socketFactory);
+
+  /**
+   * Sets the <code>HostnameVerifier</code> for this instance.
+   * 
+   * @param hostnameVerifier
+   *          the host name verifier
+   */
+  public abstract void setHostnameVerifier(HostnameVerifier hostnameVerifier);
+
+  /**
+   * Returns the server's certificate chain which was established as part of
+   * defining the session.
+   * 
+   * @return an ordered array of server certificates, with the peer's own
+   *         certificate first followed by any certificate authorities.
+   * 
+   * @throws SSLPeerUnverifiedException
+   *           if the peer is not verified.
+   * @throws IllegalStateException
+   *           if this method is called before the connection has been
+   *           established.
+   */
+  public abstract Certificate[] getServerCertificates() throws SSLPeerUnverifiedException, IllegalStateException;
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdFactory.java
index 60bf69a4..a29101f4 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdFactory.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdFactory.java
@@ -14,93 +14,93 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-package at.gv.egiz.bku.binding;
-
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Creates or converts Ids for BindingProcessors.
- * @author wbauer
- *
- */
-public class IdFactory {
-
-  public static int DEFAULT_NUMBER_OF_BITS = 168;
-
-  private static Log log = LogFactory.getLog(IdFactory.class);
-
-  private static IdFactory instance = new IdFactory();
-
-  private SecureRandom random;
-  private int numberOfBits = DEFAULT_NUMBER_OF_BITS;
-
-  private IdFactory() {
-    try {
-      random = SecureRandom.getInstance("SHA1PRNG");
-    } catch (NoSuchAlgorithmException e) {
-      log.error("Cannot instantiate secure random" + e);
-    }
-  }
-
-  public static IdFactory getInstance() {
-    return instance;
-  }
-
-
-  /**
-   * set the secure random number generator to create secure ids.
-   * 
-   * @param random
-   *          must not be null
-   */
-  public void setSecureRandom(SecureRandom random) {
-    if (random == null) {
-      throw new NullPointerException("Cannot set secure random to null");
-    }
-    this.random = random;
-  }
-
-  /**
-   * Don't use this method unless you know exactly what you do !
-   * Be sure to use a sufficient large entropy 
-   * @param numberOfBits >=1 (although this small entropy does not make sense)
-   */
-  public void setNumberOfBits(int numberOfBits) {
-    if (numberOfBits <1) {
-      throw new IllegalArgumentException("Cannot set number of bits < 1");
-    }
-    this.numberOfBits = numberOfBits;
-  }
-
-  public int getNumberOfBits() {
-    return numberOfBits;
-  }
-  
-  /**
-   * Creates a new Id object with the factory's secure RNG and the set number of
-   * bits.
-   * 
-   * @return
-   */
-  public Id createId() {
-    return new IdImpl(numberOfBits, random);
-  }
-
-  /**
-   * Creates an Id object for the provided String
-   * 
-   * @param idString
-   *          may be null in this case the method call creates a new Id.
-   * @return
-   */
-  public Id createId(String idString) {
-    if (idString == null) {
-      return createId();
-    }
-    return new IdImpl(idString);
-  }
-}
\ No newline at end of file
+package at.gv.egiz.bku.binding;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Creates or converts Ids for BindingProcessors.
+ * @author wbauer
+ *
+ */
+public class IdFactory {
+
+  private final Logger log = LoggerFactory.getLogger(IdFactory.class);
+
+  public static int DEFAULT_NUMBER_OF_BITS = 168;
+
+  private static IdFactory instance = new IdFactory();
+
+  private SecureRandom random;
+  private int numberOfBits = DEFAULT_NUMBER_OF_BITS;
+
+  private IdFactory() {
+    try {
+      random = SecureRandom.getInstance("SHA1PRNG");
+    } catch (NoSuchAlgorithmException e) {
+      log.error("Cannot instantiate secure random.", e);
+    }
+  }
+
+  public static IdFactory getInstance() {
+    return instance;
+  }
+
+
+  /**
+   * set the secure random number generator to create secure ids.
+   * 
+   * @param random
+   *          must not be null
+   */
+  public void setSecureRandom(SecureRandom random) {
+    if (random == null) {
+      throw new NullPointerException("Cannot set secure random to null");
+    }
+    this.random = random;
+  }
+
+  /**
+   * Don't use this method unless you know exactly what you do !
+   * Be sure to use a sufficient large entropy 
+   * @param numberOfBits >=1 (although this small entropy does not make sense)
+   */
+  public void setNumberOfBits(int numberOfBits) {
+    if (numberOfBits <1) {
+      throw new IllegalArgumentException("Cannot set number of bits < 1");
+    }
+    this.numberOfBits = numberOfBits;
+  }
+
+  public int getNumberOfBits() {
+    return numberOfBits;
+  }
+  
+  /**
+   * Creates a new Id object with the factory's secure RNG and the set number of
+   * bits.
+   * 
+   * @return
+   */
+  public Id createId() {
+    return new IdImpl(numberOfBits, random);
+  }
+
+  /**
+   * Creates an Id object for the provided String
+   * 
+   * @param idString
+   *          may be null in this case the method call creates a new Id.
+   * @return
+   */
+  public Id createId(String idString) {
+    if (idString == null) {
+      return createId();
+    }
+    return new IdImpl(idString);
+  }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdImpl.java
index c8a76823..096754a6 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdImpl.java
@@ -22,8 +22,8 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.security.SecureRandom;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Implementation that uses a Base64 representation for self generated Ids.
@@ -31,7 +31,8 @@ import org.apache.commons.logging.LogFactory;
  *
  */
 public class IdImpl implements at.gv.egiz.bku.binding.Id {
-  private static Log log = LogFactory.getLog(IdImpl.class);
+
+  private final Logger log = LoggerFactory.getLogger(IdImpl.class);
   
   private String idString;
 
@@ -50,7 +51,7 @@ public class IdImpl implements at.gv.egiz.bku.binding.Id {
       b64.close();
       idString = new String(baos.toByteArray());
     } catch (IOException e) {
-      log.error("Cannot create secure id: "+e);
+      log.error("Cannot create secure id.", e);
     }
   }
 
@@ -80,4 +81,4 @@ public class IdImpl implements at.gv.egiz.bku.binding.Id {
       return false;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoderFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoderFactory.java
index 211deee7..081d24d4 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoderFactory.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoderFactory.java
@@ -14,76 +14,78 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-package at.gv.egiz.bku.binding;
-
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Factory to get a matching instance for a encoded input stream when reading a http request.
- *
- */
-public class InputDecoderFactory {
-
-  public final static String MULTIPART_FORMDATA = "multipart/form-data";
-  public final static String URL_ENCODED = "application/x-www-form-urlencoded";
-
-  private static InputDecoderFactory instance = new InputDecoderFactory();
-  private static Log log = LogFactory.getLog(InputDecoderFactory.class);
-
-  private String defaultEncoding = URL_ENCODED;
-  private Map<String, Class<? extends InputDecoder>> decoderMap = new HashMap<String, Class<? extends InputDecoder>>();
-
-  private InputDecoderFactory() {
-    decoderMap.put(MULTIPART_FORMDATA, MultiPartFormDataInputDecoder.class);
-    decoderMap.put(URL_ENCODED, XWWWFormUrlInputDecoder.class);
-  }
-
-  public static InputDecoder getDefaultDecoder(InputStream is) {
-    return getDecoder(instance.defaultEncoding, is);
-  }
-
-  /**
-   * 
-   * @param contentType
-   * @param is
-   * @return null if the content type is not supported
-   */
-  public static InputDecoder getDecoder(String contentType, InputStream is) {
-    String prefix = contentType.split(";")[0].trim().toLowerCase();
-    Class<? extends InputDecoder> dec = instance.decoderMap.get(prefix);
-    if (dec == null) {
-      log.info("Unknown encoding prefix " + contentType);
-      return null;
-    }
-    InputDecoder id;
-    try {
-      id = dec.newInstance();
-      id.setContentType(contentType);
-      id.setInputStream(is);
-      return id;
-    } catch (InstantiationException e) {
-      log.error(e);
-      throw new IllegalArgumentException(
-          "Cannot get an input decoder for content type: " + contentType);
-    } catch (IllegalAccessException e) {
-      log.error(e);
-      throw new IllegalArgumentException(
-          "Cannot get an input decoder for content type: " + contentType);
-    }
-  }
-
-  /**
-   * Allows to register decoders for special mime types.
-   * @param mimeType
-   * @param decoder
-   */
-  public static void registerDecoder(String mimeType,
-      Class<? extends InputDecoder> decoder) {
-    instance.decoderMap.put(mimeType.toLowerCase(), decoder);
-  }
-}
+package at.gv.egiz.bku.binding;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Factory to get a matching instance for a encoded input stream when reading a http request.
+ *
+ */
+public class InputDecoderFactory {
+
+  public final static String MULTIPART_FORMDATA = "multipart/form-data";
+  public final static String URL_ENCODED = "application/x-www-form-urlencoded";
+
+  private static InputDecoderFactory instance = new InputDecoderFactory();
+
+  private String defaultEncoding = URL_ENCODED;
+  private Map<String, Class<? extends InputDecoder>> decoderMap = new HashMap<String, Class<? extends InputDecoder>>();
+
+  private InputDecoderFactory() {
+    decoderMap.put(MULTIPART_FORMDATA, MultiPartFormDataInputDecoder.class);
+    decoderMap.put(URL_ENCODED, XWWWFormUrlInputDecoder.class);
+  }
+
+  public static InputDecoder getDefaultDecoder(InputStream is) {
+    return getDecoder(instance.defaultEncoding, is);
+  }
+
+  /**
+   * 
+   * @param contentType
+   * @param is
+   * @return null if the content type is not supported
+   */
+  public static InputDecoder getDecoder(String contentType, InputStream is) {
+    
+    Logger log = LoggerFactory.getLogger(InputDecoderFactory.class);
+    
+    String prefix = contentType.split(";")[0].trim().toLowerCase();
+    Class<? extends InputDecoder> dec = instance.decoderMap.get(prefix);
+    if (dec == null) {
+      log.info("Unknown encoding prefix " + contentType);
+      return null;
+    }
+    InputDecoder id;
+    try {
+      id = dec.newInstance();
+      id.setContentType(contentType);
+      id.setInputStream(is);
+      return id;
+    } catch (InstantiationException e) {
+      log.error("Failed to instantiate InputDecoder.", e);
+      throw new IllegalArgumentException(
+          "Cannot get an input decoder for content type: " + contentType);
+    } catch (IllegalAccessException e) {
+      log.error("Failed to instantiate InputDecoder.", e);
+      throw new IllegalArgumentException(
+          "Cannot get an input decoder for content type: " + contentType);
+    }
+  }
+
+  /**
+   * Allows to register decoders for special mime types.
+   * @param mimeType
+   * @param decoder
+   */
+  public static void registerDecoder(String mimeType,
+      Class<? extends InputDecoder> decoder) {
+    instance.decoderMap.put(mimeType.toLowerCase(), decoder);
+  }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/MultiPartFormDataInputDecoder.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/MultiPartFormDataInputDecoder.java
index f8b13553..2dd57f12 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/MultiPartFormDataInputDecoder.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/MultiPartFormDataInputDecoder.java
@@ -14,120 +14,121 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-package at.gv.egiz.bku.binding;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Iterator;
-
-import org.apache.commons.fileupload.FileItemIterator;
-import org.apache.commons.fileupload.FileItemStream;
-import org.apache.commons.fileupload.FileUpload;
-import org.apache.commons.fileupload.FileUploadException;
-import org.apache.commons.fileupload.RequestContext;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.bku.slexceptions.SLRuntimeException;
-
-/**
- * The code to detect the multipart boundary is based on
- * org.apache.commons.fileupload.FileUploadBase of
- * http://commons.apache.org/fileupload/
- * 
- * @author wbauer
- * 
- */
-public class MultiPartFormDataInputDecoder implements InputDecoder,
-    RequestContext {
-
-  private static Log log = LogFactory
-      .getLog(MultiPartFormDataInputDecoder.class);
-
-  private String contentType;
-  private InputStream stream;
-
-  @Override
-  public void setContentType(String contentType) {
-    this.contentType = contentType;
-  }
-
-  @Override
-  public String getCharacterEncoding() {
-    return null;
-  }
-
-  @Override
-  public int getContentLength() {
-    return 0;
-  }
-
-  @Override
-  public String getContentType() {
-    return contentType;
-  }
-
-  @Override
-  public InputStream getInputStream() throws IOException {
-    return stream;
-  }
-
-  @Override
-  public Iterator<FormParameter> getFormParameterIterator() {
-    try {
-      FileUpload fup = new FileUpload();
-      FileItemIterator fit = fup.getItemIterator(this);
-      return new IteratorDelegator(fit);
-    } catch (Exception iox) {
-      log.error("Cannot decode multipart form data stream " + iox);
-      throw new SLRuntimeException(iox);
-    }
-  }
-
-  @Override
-  public void setInputStream(InputStream is) {
-    stream = is;
-  }
-
-  static class IteratorDelegator implements Iterator<FormParameter> {
-
-    private FileItemIterator fileItemIterator;
-
-    public IteratorDelegator(FileItemIterator fit) {
-      fileItemIterator = fit;
-    }
-
-    @Override
-    public boolean hasNext() {
-      try {
-        return fileItemIterator.hasNext();
-      } catch (FileUploadException e) {
-        log.error(e);
-        throw new SLRuntimeException(e);
-      } catch (IOException e) {
-        log.error(e);
-        throw new SLRuntimeException(e);
-      }
-    }
-
-    @Override
-    public FormParameter next() {
-      try {
-        FileItemStream item = fileItemIterator.next();
-        return new FormParameterImpl(item.getContentType(),
-            item.getFieldName(), item.openStream(), item.getHeaders());
-      } catch (FileUploadException e) {
-        log.error(e);
-        throw new SLRuntimeException(e);
-      } catch (IOException e) {
-        log.error(e);
-        throw new SLRuntimeException(e);
-      }
-    }
-
-    @Override
-    public void remove() {
-      throw new UnsupportedOperationException("Remove not supported");
-    }
-  }
-}
+package at.gv.egiz.bku.binding;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+
+import org.apache.commons.fileupload.FileItemIterator;
+import org.apache.commons.fileupload.FileItemStream;
+import org.apache.commons.fileupload.FileUpload;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.RequestContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+
+/**
+ * The code to detect the multipart boundary is based on
+ * org.apache.commons.fileupload.FileUploadBase of
+ * http://commons.apache.org/fileupload/
+ * 
+ * @author wbauer
+ * 
+ */
+public class MultiPartFormDataInputDecoder implements InputDecoder,
+    RequestContext {
+
+  private final Logger log = LoggerFactory.getLogger(MultiPartFormDataInputDecoder.class);
+
+  private String contentType;
+  private InputStream stream;
+
+  @Override
+  public void setContentType(String contentType) {
+    this.contentType = contentType;
+  }
+
+  @Override
+  public String getCharacterEncoding() {
+    return null;
+  }
+
+  @Override
+  public int getContentLength() {
+    return 0;
+  }
+
+  @Override
+  public String getContentType() {
+    return contentType;
+  }
+
+  @Override
+  public InputStream getInputStream() throws IOException {
+    return stream;
+  }
+
+  @Override
+  public Iterator<FormParameter> getFormParameterIterator() {
+    try {
+      FileUpload fup = new FileUpload();
+      FileItemIterator fit = fup.getItemIterator(this);
+      return new IteratorDelegator(fit);
+    } catch (Exception iox) {
+      log.error("Cannot decode multipart form data stream " + iox);
+      throw new SLRuntimeException(iox);
+    }
+  }
+
+  @Override
+  public void setInputStream(InputStream is) {
+    stream = is;
+  }
+
+  static class IteratorDelegator implements Iterator<FormParameter> {
+
+    private final Logger log = LoggerFactory.getLogger(MultiPartFormDataInputDecoder.class);
+    
+    private FileItemIterator fileItemIterator;
+
+    public IteratorDelegator(FileItemIterator fit) {
+      fileItemIterator = fit;
+    }
+
+    @Override
+    public boolean hasNext() {
+      try {
+        return fileItemIterator.hasNext();
+      } catch (FileUploadException e) {
+        log.error("Failed to get next file item.", e);
+        throw new SLRuntimeException(e);
+      } catch (IOException e) {
+        log.error("Failed to get next file item.", e);
+        throw new SLRuntimeException(e);
+      }
+    }
+
+    @Override
+    public FormParameter next() {
+      try {
+        FileItemStream item = fileItemIterator.next();
+        return new FormParameterImpl(item.getContentType(),
+            item.getFieldName(), item.openStream(), item.getHeaders());
+      } catch (FileUploadException e) {
+        log.error("Failed to get next file item.", e);
+        throw new SLRuntimeException(e);
+      } catch (IOException e) {
+        log.error("Failed to get next file item.", e);
+        throw new SLRuntimeException(e);
+      }
+    }
+
+    @Override
+    public void remove() {
+      throw new UnsupportedOperationException("Remove not supported");
+    }
+  }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/ProcessingContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/ProcessingContext.java
deleted file mode 100644
index 913259f6..00000000
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/ProcessingContext.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2008 Federal Chancellery Austria and
- * Graz University of Technology
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package at.gv.egiz.bku.binding;
-
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.concurrent.Future;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- *
- * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
- */
-public class ProcessingContext {
-
-  public static final String BINDING_PROCESSOR = "binding.processor";
-  public static final String FUTURE = "future";
-
-  protected static final Log log = LogFactory.getLog(ProcessingContext.class);
-
-  protected Map<String, Object> properties = new Hashtable<String, Object>();
-
-  public ProcessingContext(BindingProcessor bp, Future future) {
-    properties.put(BINDING_PROCESSOR, bp);
-    properties.put(FUTURE, future);
-  }
-
-  public BindingProcessor getBindingProcessor() {
-    return (BindingProcessor) properties.get(BINDING_PROCESSOR);
-  }
-
-  public Future getFuture() {
-    return (Future) properties.get(FUTURE);
-  }
-
-  public Object get(String key) {
-    return properties.get(key);
-  }
-
-  public void put(String key, Object value) {
-    properties.put(key, value);
-  }
-}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/RemovalStrategy.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/RemovalStrategy.java
deleted file mode 100644
index 6c2dcb9f..00000000
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/RemovalStrategy.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package at.gv.egiz.bku.binding;
-
-/**
- * Could be used to remove expired BindingProcessor objects from a BindingProcessorManager. 
- * 
- */
-public interface RemovalStrategy {
-  public void execute();
-  public void setBindingProcessorManager(BindingProcessorManager bp);
-}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java
index a23d96e8..c2ee4ee1 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java
@@ -16,11 +16,14 @@
  */
 package at.gv.egiz.bku.binding;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import at.gv.egiz.bku.accesscontroller.SecurityManagerFacade;
+import at.gv.egiz.bku.jmx.ComponentMXBean;
+import at.gv.egiz.bku.jmx.ComponentState;
 import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slcommands.SLCommandContext;
 import at.gv.egiz.bku.slcommands.SLCommandInvoker;
 import at.gv.egiz.bku.slcommands.SLResult;
 import at.gv.egiz.bku.slcommands.SLSourceContext;
@@ -31,10 +34,11 @@ import at.gv.egiz.bku.slexceptions.SLException;
  * This class implements the entry point for the CCEs security management.
  * 
  */
-public class SLCommandInvokerImpl implements SLCommandInvoker {
+public class SLCommandInvokerImpl implements SLCommandInvoker, ComponentMXBean {
 
-	private static Log log = LogFactory.getLog(SLCommandInvokerImpl.class);
+	private final Logger log = LoggerFactory.getLogger(SLCommandInvokerImpl.class);
 
+	protected SLCommandContext commandContext;
 	protected SLCommand command;
 	protected SLResult result;
 	protected SecurityManagerFacade securityManager;
@@ -46,12 +50,11 @@ public class SLCommandInvokerImpl implements SLCommandInvoker {
 	 */
 	public void invoke(SLSourceContext aContext) throws SLException {
 		if (securityManager == null) {
-			log.warn("Security policy not implemented yet, invoking command: "
-					+ command);
-			result = command.execute();
+			log.warn("Security policy not implemented yet, invoking command: {}.", command);
+			result = command.execute(commandContext);
 		} else {
 			if (securityManager.mayInvokeCommand(command, aContext)) {
-				result = command.execute();
+				result = command.execute(commandContext);
 			} else {
 				throw new SLException(6002);
 			}
@@ -60,9 +63,7 @@ public class SLCommandInvokerImpl implements SLCommandInvoker {
 
 	public SLResult getResult(SLTargetContext aContext) throws SLException {
 		if (securityManager == null) {
-			log
-					.warn("Security policy not implemented yet, getting result of command: "
-							+ command);
+			log.warn("Security policy not implemented yet, getting result of command: {}.", command);
 			return result;
 		} else {
 			if (securityManager.maySendResult(command, aContext)) {
@@ -73,7 +74,8 @@ public class SLCommandInvokerImpl implements SLCommandInvoker {
 		}
 	}
 
-	public void setCommand(SLCommand aCmd) {
+	public void setCommand(SLCommandContext commandContext, SLCommand aCmd) {
+	  this.commandContext = commandContext;
 		command = aCmd;
 	}
 
@@ -92,4 +94,9 @@ public class SLCommandInvokerImpl implements SLCommandInvoker {
 		this.securityManager = securityManager;
 	}
 
-}
\ No newline at end of file
+  @Override
+  public ComponentState checkComponentState() {
+    return new ComponentState(true);
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java
index 9279130d..36d5f723 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java
@@ -274,6 +274,7 @@ public class XWWWFormUrlInputIterator implements Iterator<FormParameter> {
           pos = 0;
         }
         int c2 = Character.digit(buf[pos], 16);
+        pos++;
         return ((c1 << 4) | c2);
       } else {
         return buf[pos++];
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidator.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidator.java
deleted file mode 100644
index 6a95b369..00000000
--- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidator.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package at.gv.egiz.bku.conf;
-
-import iaik.x509.X509Certificate;
-
-import java.io.File;
-
-public interface CertValidator {
-
-  public abstract void init(File certDir, File caDir);
-
-  public abstract boolean isCertificateValid(String transactionId, X509Certificate[] certs);
-
-}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java
deleted file mode 100644
index 766fe355..00000000
--- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package at.gv.egiz.bku.conf;
-
-import iaik.logging.LogConfigurationException;
-import iaik.logging.TransactionId;
-import iaik.logging.impl.TransactionIdImpl;
-import iaik.logging.LoggerConfig;
-import iaik.pki.DefaultPKIConfiguration;
-import iaik.pki.DefaultPKIProfile;
-import iaik.pki.PKIConfiguration;
-import iaik.pki.PKIException;
-import iaik.pki.PKIFactory;
-import iaik.pki.PKIModule;
-import iaik.pki.PKIProfile;
-import iaik.pki.revocation.RevocationSourceTypes;
-import iaik.pki.store.certstore.CertStoreParameters;
-import iaik.pki.store.certstore.directory.DefaultDirectoryCertStoreParameters;
-import iaik.pki.store.truststore.DefaultTrustStoreProfile;
-import iaik.pki.store.truststore.TrustStoreProfile;
-import iaik.pki.store.truststore.TrustStoreTypes;
-import iaik.x509.X509Certificate;
-
-import java.io.File;
-import java.util.Date;
-import java.util.Properties;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-public class CertValidatorImpl implements CertValidator {
-
-  private static Log log = LogFactory.getLog(CertValidatorImpl.class);
-
-  private PKIFactory pkiFactory;
-  private PKIProfile profile;
-
-  public CertValidatorImpl() {
-
-  }
-
-  /* (non-Javadoc)
-   * @see at.gv.egiz.bku.conf.CertValidator#init(java.io.File, java.io.File)
-   */
-  public void init(File certDir, File caDir) {
-    // initialize IAIK logging for PKI module
-    log.debug("Configuring logging for IAIK PKI module");
-    iaik.logging.LogFactory.configure(new LoggerConfig() {
-      
-      @Override
-      public Properties getProperties() throws LogConfigurationException {
-        return null;
-      }
-      
-      @Override
-      public String getNodeId() {
-        return "pki";
-      }
-      
-      @Override
-      public String getFactory() {
-        return IAIKCommonsLogFactory.class.getName();
-      }
-    });
-    
-    
-    // the parameters specifying the directory certstore
-    CertStoreParameters[] certStoreParameters = { new DefaultDirectoryCertStoreParameters(
-        "CS-001", certDir.getAbsolutePath(), true, false) };
-
-    // create a new PKI configuration using the certstore parameters
-    PKIConfiguration pkiConfig = new DefaultPKIConfiguration(
-        certStoreParameters);
-
-    // Transaction ID for logging
-    TransactionId tid = new TransactionIdImpl("Configure-PKI");
-    // get PKI factory for creating PKI module(s)
-    pkiFactory = PKIFactory.getInstance();
-    // configure the factory
-    try {
-      pkiFactory.configure(pkiConfig, tid);
-    } catch (PKIException e) {
-      log.error("Cannot configure PKI module", e);
-    }
-    // the truststore to be used
-    TrustStoreProfile trustProfile = new DefaultTrustStoreProfile("TS-001",
-        TrustStoreTypes.DIRECTORY, caDir.getAbsolutePath());
-    profile = new DefaultPKIProfile(trustProfile);
-    ((DefaultPKIProfile)profile).setAutoAddCertificates(true);
-    ((DefaultPKIProfile) profile).setPreferredServiceOrder(new String[] {
-        RevocationSourceTypes.OCSP, RevocationSourceTypes.CRL });
-  }
-
-  /* (non-Javadoc)
-   * @see at.gv.egiz.bku.conf.CertValidator#isCertificateValid(java.lang.String, iaik.x509.X509Certificate[])
-   */
-  public boolean isCertificateValid(String transactionId,
-      X509Certificate[] certs) {
-    // Transaction ID for logging
-    TransactionId tid = new TransactionIdImpl(transactionId);
-    // get a PKIModule
-    PKIModule pkiModule;
-    try {
-      pkiModule = pkiFactory.getPKIModule(profile);
-      return pkiModule.validateCertificate(new Date(), certs[0], certs, null,
-          tid).isCertificateValid();
-    } catch (PKIException e) {
-      log.error("Cannot validate certificate", e);
-    }
-    return false;
-  }
-}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configuration.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configuration.java
deleted file mode 100644
index f813b14d..00000000
--- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configuration.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2008 Federal Chancellery Austria and
- * Graz University of Technology
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package at.gv.egiz.bku.conf;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * BKU Common Configuration
- * 
- * Injected to BKU Common classes as defined in mocca-conf.xml
- * 
- * Replace at.gv.egiz.bku.conf.Configurator,
- * currently only few configuration options are supported.
- *
- * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
- */
-public class Configuration {
-
-  public static final int MAX_DATAURL_HOPS_DEFAULT = 50;
-  public static final String IMPLEMENTATION_NAME_DEFAULT = "MOCCA";
-  public static final String IMPLEMENTATION_VERSION_DEFAULT = "UNKNOWN";
-
-  private static final Log log = LogFactory.getLog(Configuration.class);
-
-  private int maxDataUrlHops = -1;
-  private String implementationName;
-  private String implementationVersion;
-
-  public void setMaxDataUrlHops(int maxDataUrlHops) {
-    this.maxDataUrlHops = maxDataUrlHops;
-  }
-
-  /**
-	 * Defines the maximum number of dataurl connects that are allowed within a
-	 * single SL Request processing.
-	 */
-  public int getMaxDataUrlHops() {
-    if (maxDataUrlHops < 0) {
-      log.warn("maxDataUrlHops not configured, using default: " + MAX_DATAURL_HOPS_DEFAULT);
-      return MAX_DATAURL_HOPS_DEFAULT;
-    }
-    return maxDataUrlHops;
-  }
-
-  /**
-   * @return the implementationName
-   */
-  public String getImplementationName() {
-    if (implementationName == null) {
-      log.info("implementationName not configured, using default: " + IMPLEMENTATION_NAME_DEFAULT);
-      return "MOCCA";
-    }
-    return implementationName;
-  }
-
-  /**
-   * @param implementationName the implementationName to set
-   */
-  public void setImplementationName(String implementationName) {
-    this.implementationName = implementationName;
-  }
-
-  /**
-   * @return the implementationVersion
-   */
-  public String getImplementationVersion() {
-    if (implementationName == null) {
-      log.info("implementationName not configured, using default: " + IMPLEMENTATION_VERSION_DEFAULT);
-      return IMPLEMENTATION_VERSION_DEFAULT;
-    }
-    return implementationVersion;
-  }
-
-  /**
-   * @param implementationVersion the implementationVersion to set
-   */
-  public void setImplementationVersion(String implementationVersion) {
-    this.implementationVersion = implementationVersion;
-  }
-
-
-
-
-}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java
deleted file mode 100644
index 50f5d2b4..00000000
--- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java
+++ /dev/null
@@ -1,467 +0,0 @@
-package at.gv.egiz.bku.conf;
-
-import iaik.security.ecc.provider.ECCProvider;
-import iaik.security.provider.IAIK;
-import iaik.xml.crypto.XSecProvider;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.security.GeneralSecurityException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.security.Provider.Service;
-import java.security.cert.CertStore;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.CollectionCertStoreParameters;
-import java.security.cert.LDAPCertStoreParameters;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-import java.util.jar.Attributes;
-import java.util.jar.Manifest;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.bku.binding.DataUrl;
-import at.gv.egiz.bku.slcommands.impl.xsect.DataObject;
-import at.gv.egiz.bku.slcommands.impl.xsect.STALProvider;
-import at.gv.egiz.bku.slexceptions.SLRuntimeException;
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
-import javax.net.ssl.SSLSocketFactory;
-
-public abstract class Configurator {
-
-  private Log log = LogFactory.getLog(Configurator.class);
-
-  public final static String USERAGENT_CONFIG_P = "UserAgent";
-  public static final String DATAURLCONNECTION_CONFIG_P = "DataURLConnectionImplClass";
-
-  public static final String USERAGENT_DEFAULT = "citizen-card-environment/1.2 MOCCA/UNKNOWN";
-  public static final String USERAGENT_BASE = "citizen-card-environment/1.2 MOCCA/";
-
-  public static final String SIGNATURE_LAYOUT = "SignatureLayout";
-
-  protected Properties properties;
-
-  protected CertValidator certValidator;
-  protected String signaturLayoutVersion;
-
-  protected Configurator() {
-  }
-
-  protected abstract File getCertDir();
-
-  protected abstract File getCADir();
-
-  protected abstract InputStream getManifest();
-
-  private X509Certificate[] getCACerts() throws IOException,
-      CertificateException {
-    List<X509Certificate> caCerts = new ArrayList<X509Certificate>();
-    File caDir = getCADir();
-    if (caDir != null) {
-      if (!caDir.isDirectory()) {
-        log.error("Expecting directory as SSL.caDirectory parameter");
-        throw new SLRuntimeException(
-            "Expecting directory as SSL.caDirectory parameter");
-      }
-      log.info("loading trustStore from " + caDir.getAbsolutePath());
-      CertificateFactory cf = CertificateFactory.getInstance("X.509");
-      for (File f : caDir.listFiles()) {
-        try {
-          FileInputStream fis = new FileInputStream(f);
-          X509Certificate cert = (X509Certificate) cf.generateCertificate(fis);
-          fis.close();
-          log.debug("Adding trusted cert " + cert.getSubjectDN());
-          caCerts.add(cert);
-        } catch (Exception e) {
-          log.error("Cannot add trusted ca", e);
-        }
-      }
-      return caCerts.toArray(new X509Certificate[caCerts.size()]);
-    } else {
-      log.warn("No CA certificates configured");
-    }
-    return null;
-  }
-
-  protected List<CertStore> getCertstore() throws IOException,
-      CertificateException, InvalidAlgorithmParameterException,
-      NoSuchAlgorithmException {
-    List<CertStore> resultList = new ArrayList<CertStore>();
-    File certDir = getCertDir();
-    if (certDir != null) {
-      if (!certDir.isDirectory()) {
-        log.error("Expecting directory as SSL.certDirectory parameter");
-        throw new SLRuntimeException(
-            "Expecting directory as SSL.certDirectory parameter");
-      }
-      log.info("loading certStore from " + certDir.getAbsolutePath());
-      List<X509Certificate> certCollection = new LinkedList<X509Certificate>();
-      CertificateFactory cf = CertificateFactory.getInstance("X.509");
-      for (File f : certDir.listFiles()) {
-        try {
-          FileInputStream fis = new FileInputStream(f);
-          X509Certificate cert = (X509Certificate) cf.generateCertificate(fis);
-          certCollection.add(cert);
-          fis.close();
-          log
-              .trace("Added following cert to certstore: "
-                  + cert.getSubjectDN());
-        } catch (Exception ex) {
-          log.error("Cannot add certificate", ex);
-        }
-      }
-      CollectionCertStoreParameters csp = new CollectionCertStoreParameters(
-          certCollection);
-      resultList.add(CertStore.getInstance("Collection", csp));
-      log.info("Added collection certstore");
-    } else {
-      log.warn("No certstore directory configured");
-    }
-    String ldapHost = getProperty("SSL.ldapServer");
-    if ((ldapHost != null) && (!"".equals(ldapHost))) {
-      String ldapPortString = getProperty("SSL.ldapPort");
-      int ldapPort = 389;
-      if (ldapPortString != null) {
-        try {
-          ldapPort = Integer.parseInt(ldapPortString);
-        } catch (NumberFormatException nfe) {
-          log.error("Invalid ldap port, using default 389");
-        }
-      } else {
-        log.warn("ldap port not specified, using default 389");
-      }
-      LDAPCertStoreParameters ldapParams = new LDAPCertStoreParameters(
-          ldapHost, ldapPort);
-      resultList.add(CertStore.getInstance("LDAP", ldapParams));
-      log.info("Added LDAP certstore");
-    }
-    return resultList;
-  }
-
-  protected void configUrlConnections() {
-    HttpsURLConnection.setFollowRedirects(false);
-    HttpURLConnection.setFollowRedirects(false);
-  }
-
-  protected void configureProviders() {
-    log.debug("Registering security providers");
-    
-    IAIK iaikProvider = new IAIK();
-    if (Security.getProvider(iaikProvider.getName()) == null) {
-      // register IAIK provider at first position
-      Security.insertProviderAt(iaikProvider, 1);
-    } else {
-      // IAIK provider already registered
-      log.info("Provider " + iaikProvider.getName() + " already registered.");
-    }
-
-    ECCProvider eccProvider = new ECCProvider(false);
-    if (Security.getProvider(eccProvider.getName()) == null) {
-      // register ECC Provider at second position
-      Security.insertProviderAt(eccProvider, 2);
-    } else {
-      // ECC Provider already registered
-      log.info("Provider " + eccProvider.getName() + " already registered."); 
-    }
-
-    // registering STALProvider as delegation provider for XSECT
-    STALProvider stalProvider = new STALProvider();
-    if (Security.getProvider(stalProvider.getName()) == null) {
-      // register STAL provider
-      Set<Service> services = stalProvider.getServices();
-      StringBuilder sb = new StringBuilder();
-      for (Service service : services) {
-        String algorithm = service.getType() + "." + service.getAlgorithm();
-        XSecProvider.setDelegationProvider(algorithm, stalProvider.getName());
-        sb.append("\n" + algorithm);
-      }
-      log
-          .debug("Registered STALProvider as XSecProvider delegation provider for the following services : "
-              + sb.toString());
-
-      Security.addProvider(stalProvider);
-    } else {
-      // STAL Provider already registered
-      log.info("Provider " + stalProvider.getName() + " already registered."); 
-    }
-    
-    if (Security.getProvider(XSecProvider.NAME) == null) {
-      // register XML Security provider
-      XSecProvider.addAsProvider(false);
-    } else {
-      log.info("Provider " + XSecProvider.NAME + " already registered.");
-    }
-    
-    if (log.isDebugEnabled()) {
-      StringBuilder sb = new StringBuilder();
-      sb.append("Registered providers: ");
-      int i = 1;
-      for (Provider prov : Security.getProviders()) {
-        sb.append((i++) + ". : " + prov);
-      }
-      log.debug(sb.toString());
-    }
-  }
-
-  protected void configViewer() {
-    String bv = properties.getProperty("ValidateHashDataInputs");
-    if (bv != null) {
-      DataObject.enableHashDataInputValidation(Boolean.parseBoolean(bv));
-    } else {
-      log.warn("ValidateHashDataInputs not set, falling back to default");
-    }
-  }
-
-  public void configureSingatureLayoutVersion() {
-    if (properties.get(SIGNATURE_LAYOUT) == null) {
-      try {
-        String classContainer = Configurator.class.getProtectionDomain()
-            .getCodeSource().getLocation().toString();
-        URL manifestUrl = new URL("jar:" + classContainer
-            + "!/META-INF/MANIFEST.MF");
-        Manifest manifest = new Manifest(manifestUrl.openStream());
-        Attributes att = manifest.getMainAttributes();
-        String layout = null;
-        if (att != null) {
-          layout = att.getValue(SIGNATURE_LAYOUT);
-        }
-        if (layout != null) {
-          log.info("setting SignatureLayout header to " + layout);
-          properties.put(SIGNATURE_LAYOUT, layout);
-        } else {
-          log.warn("no SignatureLayout version defined");
-        }
-      } catch (Exception ex) {
-        log.warn("Cannot read manifest", ex);
-      }
-    }
-  }
-
-  public void configureNetwork() {
-    String proxy = getProperty("HTTPProxyHost");
-    String portString = getProperty("HTTPProxyPort");
-    if ((proxy == null) || (proxy.equals(""))) {
-      log.info("No proxy configured");
-    } else {
-      log.info("Setting proxy to: " + proxy + ":" + portString);
-      System.setProperty("proxyHost", proxy);
-      System.setProperty("proxyPort", portString);
-    }
-    String timeout = getProperty("DefaultSocketTimeout");
-    if ((timeout != null) && (!timeout.equals(""))) {
-      System.setProperty("sun.net.client.defaultConnectTimeout", timeout);
-    }
-  }
-
-  public void configureVersion() {
-    if (properties.getProperty(USERAGENT_CONFIG_P) == null) {
-      Properties p = new Properties();
-      try {
-        InputStream is = getManifest();
-        if (is != null) {
-          p.load(getManifest());
-          String version = p.getProperty("Implementation-Build");
-          if (version == null) {
-            version="UNKNOWN";
-          }
-          properties.setProperty(USERAGENT_CONFIG_P, USERAGENT_BASE + version);
-          log.debug("Setting user agent to: "
-              + properties.getProperty(USERAGENT_CONFIG_P));
-        } else {
-          log.warn("Failed to read manifest, setting user-agent to " + USERAGENT_DEFAULT);
-          properties.setProperty(USERAGENT_CONFIG_P, USERAGENT_DEFAULT);
-        }
-      } catch (IOException e) {
-        log.error(e);
-      }
-    } else {
-      log.info("using configured user agent " + properties.getProperty(USERAGENT_CONFIG_P));
-    }
-  }
-
-  /**
-   * TODO cleanup configuration (read MANIFEST, DataURLconfig,...)
-   */
-  public void configure() {
-    configureProviders();
-    configUrlConnections();
-    configViewer();
-    configureSSL();
-    configureVersion();
-    configureSingatureLayoutVersion();
-    configureNetwork();
-    //after configureVersion() and configureSignatureLayoutVersion()
-    DataUrl.setConfiguration(properties);
-  }
-
-  public void setConfiguration(Properties props) {
-    this.properties = props;
-  }
-
-  public String getProperty(String key) {
-    if (properties != null) {
-      return properties.getProperty(key);
-    }
-    return null;
-  }
-
-  public void configureSSL() {
-    X509Certificate[] caCerts = null;
-    try {
-      caCerts = getCACerts();
-    } catch (Exception e1) {
-      log.error("Cannot load CA certificates", e1);
-    }
-    String disableAll = getProperty("SSL.disableAllChecks");
-    String disableHostnameVerification = getProperty("SSL.disableHostnameVerification");
-    try {
-      KeyManager[] km = null;
-      SSLContext sslCtx = SSLContext
-          .getInstance(getProperty("SSL.sslProtocol"));
-      if ((disableAll != null) && (Boolean.parseBoolean(disableAll))) {
-        log.warn("--------------------------------------");
-        log.warn(" Disabling SSL Certificate Validation ");
-        log.warn("--------------------------------------");
-
-        sslCtx.init(km,
-            new TrustManager[] { new MyAlwaysTrustManager(caCerts) }, null);
-      } else {
-        MyPKITrustManager pkixTM = new MyPKITrustManager(certValidator,
-            getCertDir(), getCADir(), caCerts);
-        sslCtx.init(km, new TrustManager[] { pkixTM }, null);
-      }
-      DataUrl.setSSLSocketFactory(sslCtx.getSocketFactory());
-      URLDereferencer.getInstance().setSSLSocketFactory(
-          sslCtx.getSocketFactory());
-    } catch (Exception e) {
-      log.error("Cannot configure SSL", e);
-    }
-    if ((disableAll != null && Boolean.parseBoolean(disableAll))
-        || (disableHostnameVerification != null && Boolean
-            .parseBoolean(disableHostnameVerification))) {
-      log.warn("---------------------------------");
-      log.warn(" Disabling Hostname Verification ");
-      log.warn("---------------------------------");
-      DataUrl.setHostNameVerifier(new HostnameVerifier() {
-        @Override
-        public boolean verify(String hostname, SSLSession session) {
-          return true;
-        }
-      });
-      URLDereferencer.getInstance().setHostnameVerifier(new HostnameVerifier() {
-        @Override
-        public boolean verify(String hostname, SSLSession session) {
-          return true;
-        }
-      });
-    }
-  }
-
-  public void setCertValidator(CertValidator certValidator) {
-    this.certValidator = certValidator;
-  }
-
-  private static class MyPKITrustManager implements X509TrustManager {
-    private static Log log = LogFactory.getLog(MyPKITrustManager.class);
-
-    private CertValidator certValidator;
-    private X509Certificate[] trustedCerts;
-
-    public MyPKITrustManager(CertValidator cv, File certStore, File trustStore,
-        X509Certificate[] trustedCerts) {
-      certValidator = cv;
-      certValidator.init(certStore, trustStore);
-      this.trustedCerts = trustedCerts;
-    }
-
-    @Override
-    public void checkClientTrusted(X509Certificate[] chain, String authType)
-        throws CertificateException {
-      log.error("Did not expect this method to get called");
-      throw new CertificateException("Method not implemented");
-    }
-
-    private static iaik.x509.X509Certificate[] convertCerts(
-        X509Certificate[] certs) throws GeneralSecurityException {
-      iaik.x509.X509Certificate[] retVal = new iaik.x509.X509Certificate[certs.length];
-      int i = 0;
-      for (X509Certificate cert : certs) {
-        if (cert instanceof iaik.x509.X509Certificate) {
-          retVal[i++] = (iaik.x509.X509Certificate) cert;
-        } else {
-          retVal[i++] = new iaik.x509.X509Certificate(cert.getEncoded());
-        }
-      }
-      return retVal;
-    }
-
-    @Override
-    public void checkServerTrusted(X509Certificate[] chain, String authType)
-        throws CertificateException {
-      try {
-        boolean valid = certValidator.isCertificateValid(Thread.currentThread()
-            .getName(), convertCerts(chain));
-        if (!valid) {
-          throw new CertificateException("Certificate not valid");
-        }
-      } catch (GeneralSecurityException e) {
-        throw new CertificateException(e);
-      }
-    }
-
-    @Override
-    public X509Certificate[] getAcceptedIssuers() {
-      return trustedCerts;
-    }
-  }
-
-  private static class MyAlwaysTrustManager implements X509TrustManager {
-    private static Log log = LogFactory.getLog(MyAlwaysTrustManager.class);
-    private X509Certificate[] trustedCerts;
-
-    public MyAlwaysTrustManager(X509Certificate[] trustedCerts) {
-      this.trustedCerts = trustedCerts;
-    }
-
-    @Override
-    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
-        throws CertificateException {
-      log.error("Did not expect this method to get called");
-      throw new CertificateException("Method not implemented");
-    }
-
-    @Override
-    public void checkServerTrusted(X509Certificate[] certs, String arg1)
-        throws CertificateException {
-      log.warn("-------------------------------------");
-      log.warn("SSL Certificate Validation Disabled !");
-      log.warn("-------------------------------------");
-    }
-
-    @Override
-    public X509Certificate[] getAcceptedIssuers() {
-      return trustedCerts;
-    }
-  }
-}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java
deleted file mode 100644
index 1b7dd189..00000000
--- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * 
- */
-package at.gv.egiz.bku.conf;
-
-import iaik.logging.Log;
-import iaik.logging.TransactionId;
-
-/**
- * @author mcentner
- *
- */
-public class IAIKCommonsLog implements Log {
-  
-  /**
-   * The id that will be written to the log if the transactionid == null
-   */
-  public final static String NO_ID = "Null-ID";
-
-  protected org.apache.commons.logging.Log commonsLog;
-  
-  protected String nodeId;
-
-  public IAIKCommonsLog(org.apache.commons.logging.Log log) {
-    this.commonsLog = log;
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.Log#debug(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
-   */
-  @Override
-  public void debug(TransactionId transactionId, Object message, Throwable t) {
-    if (commonsLog.isDebugEnabled()) {
-      commonsLog.debug(nodeId + ": "
-          + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
-          + message, t);
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.Log#info(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
-   */
-  @Override
-  public void info(TransactionId transactionId, Object message, Throwable t) {
-    if (commonsLog.isInfoEnabled()) {
-      commonsLog.info(nodeId + ": "
-          + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
-          + message, t);
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.Log#warn(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
-   */
-  @Override
-  public void warn(TransactionId transactionId, Object message, Throwable t) {
-    if (commonsLog.isWarnEnabled()) {
-      commonsLog.warn(nodeId + ": "
-          + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
-          + message, t);
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.Log#error(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
-   */
-  @Override
-  public void error(TransactionId transactionId, Object message, Throwable t) {
-    if (commonsLog.isErrorEnabled()) {
-      commonsLog.error(nodeId + ": "
-          + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
-          + message, t);
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.Log#fatal(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
-   */
-  @Override
-  public void fatal(TransactionId transactionId, Object message, Throwable t) {
-    if (commonsLog.isFatalEnabled()) {
-      commonsLog.fatal(nodeId + ": "
-          + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
-          + message, t);
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.Log#setNodeId(java.lang.String)
-   */
-  @Override
-  public void setNodeId(String nodeId) {
-    this.nodeId = nodeId;
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.Log#getNodeId()
-   */
-  @Override
-  public String getNodeId() {
-    return nodeId;
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.Log#isDebugEnabled()
-   */
-  @Override
-  public boolean isDebugEnabled() {
-    return commonsLog.isDebugEnabled();
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.Log#isInfoEnabled()
-   */
-  @Override
-  public boolean isInfoEnabled() {
-    return commonsLog.isInfoEnabled();
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.Log#isWarnEnabled()
-   */
-  @Override
-  public boolean isWarnEnabled() {
-    return commonsLog.isWarnEnabled();
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.Log#isErrorEnabled()
-   */
-  @Override
-  public boolean isErrorEnabled() {
-    return commonsLog.isErrorEnabled();
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.Log#isFatalEnabled()
-   */
-  @Override
-  public boolean isFatalEnabled() {
-    return commonsLog.isFatalEnabled();
-  }
-
-}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java
deleted file mode 100644
index 14e2c757..00000000
--- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * 
- */
-package at.gv.egiz.bku.conf;
-
-import org.apache.commons.logging.impl.WeakHashtable;
-
-import iaik.logging.Log;
-import iaik.logging.LogConfigurationException;
-import iaik.logging.LogFactory;
-
-/**
- * @author mcentner
- *
- */
-public class IAIKCommonsLogFactory extends LogFactory {
-
-  protected WeakHashtable instances = new WeakHashtable();
-  
-  /* (non-Javadoc)
-   * @see iaik.logging.LogFactory#getInstance(java.lang.String)
-   */
-  @Override
-  public Log getInstance(String name) throws LogConfigurationException {
-    org.apache.commons.logging.Log commonsLog = org.apache.commons.logging.LogFactory.getLog(name);
-    Log log = (Log) instances.get(commonsLog);
-    if (log == null) {
-      log = new IAIKCommonsLog(commonsLog);
-      log.setNodeId(node_id_);
-      instances.put(commonsLog, log);
-    }
-    return log;
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.LogFactory#getInstance(java.lang.Class)
-   */
-  @SuppressWarnings("unchecked")
-  @Override
-  public Log getInstance(Class clazz) throws LogConfigurationException {
-    org.apache.commons.logging.Log commonsLog = org.apache.commons.logging.LogFactory.getLog(clazz);
-    Log log = (Log) instances.get(commonsLog);
-    if (log == null) {
-      log = new IAIKCommonsLog(commonsLog);
-      log.setNodeId(node_id_);
-      instances.put(commonsLog, log);
-    }
-    return log;
-  }
-
-  /* (non-Javadoc)
-   * @see iaik.logging.LogFactory#release()
-   */
-  @Override
-  public void release() {
-    instances.clear();
-  }
-
-}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapter.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapter.java
new file mode 100644
index 00000000..b04509a0
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapter.java
@@ -0,0 +1,146 @@
+/**
+ * 
+ */
+package at.gv.egiz.bku.conf;
+
+import org.slf4j.Logger;
+
+import iaik.logging.Log;
+import iaik.logging.TransactionId;
+
+/**
+ * @author mcentner
+ *
+ */
+public class IAIKLogAdapter implements Log {
+  
+  /**
+   * The id that will be written to the log if the transactionid == null
+   */
+  public final static String NO_ID = "Null-ID";
+
+  protected Logger log;
+  
+  protected String nodeId;
+
+  public IAIKLogAdapter(Logger logger) {
+    this.log = logger;
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.Log#debug(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
+   */
+  @Override
+  public void debug(TransactionId transactionId, Object message, Throwable t) {
+    if (log.isDebugEnabled()) {
+      log.debug(nodeId + ": "
+          + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
+          + message, t);
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.Log#info(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
+   */
+  @Override
+  public void info(TransactionId transactionId, Object message, Throwable t) {
+    if (log.isInfoEnabled()) {
+      log.info(nodeId + ": "
+          + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
+          + message, t);
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.Log#warn(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
+   */
+  @Override
+  public void warn(TransactionId transactionId, Object message, Throwable t) {
+    if (log.isWarnEnabled()) {
+      log.warn(nodeId + ": "
+          + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
+          + message, t);
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.Log#error(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
+   */
+  @Override
+  public void error(TransactionId transactionId, Object message, Throwable t) {
+    if (log.isErrorEnabled()) {
+      log.error(nodeId + ": "
+          + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
+          + message, t);
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.Log#fatal(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
+   */
+  @Override
+  public void fatal(TransactionId transactionId, Object message, Throwable t) {
+    if (log.isErrorEnabled()) {
+      log.error(nodeId + ": "
+          + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
+          + message, t);
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.Log#setNodeId(java.lang.String)
+   */
+  @Override
+  public void setNodeId(String nodeId) {
+    this.nodeId = nodeId;
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.Log#getNodeId()
+   */
+  @Override
+  public String getNodeId() {
+    return nodeId;
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.Log#isDebugEnabled()
+   */
+  @Override
+  public boolean isDebugEnabled() {
+    return log.isDebugEnabled();
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.Log#isInfoEnabled()
+   */
+  @Override
+  public boolean isInfoEnabled() {
+    return log.isInfoEnabled();
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.Log#isWarnEnabled()
+   */
+  @Override
+  public boolean isWarnEnabled() {
+    return log.isWarnEnabled();
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.Log#isErrorEnabled()
+   */
+  @Override
+  public boolean isErrorEnabled() {
+    return log.isErrorEnabled();
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.Log#isFatalEnabled()
+   */
+  @Override
+  public boolean isFatalEnabled() {
+    return log.isErrorEnabled();
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapterFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapterFactory.java
new file mode 100644
index 00000000..52c3d8d1
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapterFactory.java
@@ -0,0 +1,62 @@
+/**
+ * 
+ */
+package at.gv.egiz.bku.conf;
+
+import java.util.WeakHashMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import iaik.logging.Log;
+import iaik.logging.LogConfigurationException;
+import iaik.logging.LogFactory;
+
+/**
+ * @author mcentner
+ *
+ */
+public class IAIKLogAdapterFactory extends LogFactory {
+
+  protected WeakHashMap<Logger, Log> instances = new WeakHashMap<Logger, Log>();
+  
+  /* (non-Javadoc)
+   * @see iaik.logging.LogFactory#getInstance(java.lang.String)
+   */
+  @Override
+  public synchronized Log getInstance(String name) throws LogConfigurationException {
+    Logger logger = LoggerFactory.getLogger(name);
+    Log log = instances.get(logger);
+    if (log == null) {
+      log = new IAIKLogAdapter(logger);
+      log.setNodeId(node_id_);
+      instances.put(logger, log);
+    }
+    return log;
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.LogFactory#getInstance(java.lang.Class)
+   */
+  @SuppressWarnings("unchecked")
+  @Override
+  public synchronized Log getInstance(Class clazz) throws LogConfigurationException {
+    Logger logger = LoggerFactory.getLogger(clazz);
+    Log log = instances.get(logger);
+    if (log == null) {
+      log = new IAIKLogAdapter(logger);
+      log.setNodeId(node_id_);
+      instances.put(logger, log);
+    }
+    return log;
+  }
+
+  /* (non-Javadoc)
+   * @see iaik.logging.LogFactory#release()
+   */
+  @Override
+  public void release() {
+    instances.clear();
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/MoccaConfigurationFacade.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/MoccaConfigurationFacade.java
new file mode 100644
index 00000000..52842167
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/MoccaConfigurationFacade.java
@@ -0,0 +1,22 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.conf;
+
+public interface MoccaConfigurationFacade {
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentMXBean.java b/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentMXBean.java
new file mode 100644
index 00000000..cb501b92
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentMXBean.java
@@ -0,0 +1,27 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.jmx;
+
+import javax.management.MXBean;
+
+@MXBean
+public interface ComponentMXBean {
+
+  public ComponentState checkComponentState();
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentState.java b/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentState.java
new file mode 100644
index 00000000..9da8515f
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentState.java
@@ -0,0 +1,38 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.jmx;
+
+import java.beans.ConstructorProperties;
+
+public class ComponentState {
+
+  boolean ready;
+
+  @ConstructorProperties({"ready"})
+  public ComponentState(boolean ready) {
+    this.ready = ready;
+  }
+
+  /**
+   * @return the ready
+   */
+  public boolean isReady() {
+    return ready;
+  }
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentStateCheck.java b/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentStateCheck.java
new file mode 100644
index 00000000..562c2213
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentStateCheck.java
@@ -0,0 +1,24 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.jmx;
+
+public interface ComponentStateCheck {
+  
+    
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/AbstractSLCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/AbstractSLCommandFactory.java
new file mode 100644
index 00000000..951e09f4
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/AbstractSLCommandFactory.java
@@ -0,0 +1,46 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands;
+
+import javax.xml.bind.JAXBElement;
+
+import org.apache.commons.configuration.Configuration;
+
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+
+public abstract class AbstractSLCommandFactory {
+  
+  protected Configuration configuration;
+  
+  public abstract SLCommand createSLCommand(JAXBElement<?> object) throws SLCommandException;
+
+  /**
+   * @return the configuration
+   */
+  public Configuration getConfiguration() {
+    return configuration;
+  }
+
+  /**
+   * @param configuration the configuration to set
+   */
+  public void setConfiguration(Configuration configuration) {
+    this.configuration = configuration;
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureCommand.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureCommand.java
index 2d87c39f..7db0098b 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureCommand.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureCommand.java
@@ -21,5 +21,5 @@ import at.gv.egiz.bku.slexceptions.SLRequestException;
 
 public interface CreateXMLSignatureCommand extends SLCommand {
 
-  public void prepareXMLSignature() throws SLCommandException, SLRequestException;
+  public void prepareXMLSignature(SLCommandContext commandContext) throws SLCommandException, SLRequestException;
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureResult.java
index 4bc2820b..f27fd905 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureResult.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureResult.java
@@ -15,6 +15,11 @@
 * limitations under the License.
 */
 package at.gv.egiz.bku.slcommands;
+
+import org.w3c.dom.Element;
 
-public interface CreateXMLSignatureResult extends SLResult {
+public interface CreateXMLSignatureResult extends SLResult {
+  
+  public Element getContent();
+  
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/ErrorResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/ErrorResult.java
index 5d52c0ea..5663627e 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/ErrorResult.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/ErrorResult.java
@@ -15,6 +15,12 @@
 * limitations under the License.
 */
 package at.gv.egiz.bku.slcommands;
+
 
-public interface ErrorResult extends SLResult {
+public interface ErrorResult extends SLResult {
+  
+  public int getErrorCode();
+  
+  public String getInfo();
+  
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadResult.java
index c6a51362..599f1ae0 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadResult.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadResult.java
@@ -16,5 +16,8 @@
 */
 package at.gv.egiz.bku.slcommands;
 
-public interface InfoboxReadResult extends SLResult {
+public interface InfoboxReadResult extends SLResult {
+  
+  public Object getContent();
+  
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommand.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommand.java
index a8625946..d24c86ef 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommand.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommand.java
@@ -20,12 +20,16 @@ import at.gv.egiz.bku.slexceptions.SLCommandException;
 
 public interface SLCommand {
   
-  public final String NAMESPACE_URI = "http://www.buergerkarte.at/namespaces/securitylayer/1.2#";
+  public final String NAMESPACE_URI = "http://www.buergerkarte.at/namespaces/securitylayer/1.2#";
+  
+  public final String NAMESPACE_URI_20020225 = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#";
+  
+  public final String NAMESPACE_URI_20020831 = "http://www.buergerkarte.at/namespaces/securitylayer/20020831#";
   
   public String getName();
 
-  public void init(SLCommandContext aCtx, Object aUnmarshalledRequest) throws SLCommandException;
+  public void init(Object aUnmarshalledRequest) throws SLCommandException;
 
-  public SLResult execute();
+  public SLResult execute(SLCommandContext commandContext);
 
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandContext.java
index 5af2afac..f0e46d0c 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandContext.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandContext.java
@@ -18,30 +18,43 @@ package at.gv.egiz.bku.slcommands;
 
 import java.util.Locale;
 
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
 import at.gv.egiz.stal.STAL;
 
 public class SLCommandContext {
   
-  private STAL stal;
-  private URLDereferencerContext urlDerefCtx;
+  private STAL stal;
+  
+  private URLDereferencer urlDereferencer;
   
-  private Locale locale;
-
+  private Locale locale;
+
+  public SLCommandContext(STAL stal, URLDereferencer urlDereferencer) {
+    this.stal = stal;
+    this.urlDereferencer = urlDereferencer;
+  }
+
+  public SLCommandContext(STAL stal, URLDereferencer urlDereferencer,
+      Locale locale) {
+    this.stal = stal;
+    this.urlDereferencer = urlDereferencer;
+    this.locale = locale;
+  }
+
   public void setSTAL(STAL aStal) {
     this.stal = aStal;
   }
 
-  public void setURLDereferencerContext(URLDereferencerContext aCtx) {
-    this.urlDerefCtx = aCtx;
+  public void setURLDereferencer(URLDereferencer urlDereferencer) {
+    this.urlDereferencer = urlDereferencer;
   }
 
   public STAL getSTAL() {
     return stal;
   }
 
-  public URLDereferencerContext getURLDereferencerContext() {
-    return urlDerefCtx;
+  public URLDereferencer getURLDereferencer() {
+    return urlDereferencer;
   }
 
   public Locale getLocale() {
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java
index ab2f08cc..0314869e 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java
@@ -16,390 +16,211 @@
 */
 package at.gv.egiz.bku.slcommands;
 
-import java.io.IOException;
-import java.net.URL;
 import java.util.HashMap;
 import java.util.Map;
 
-import javax.xml.XMLConstants;
-import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.UnmarshalException;
 import javax.xml.bind.Unmarshaller;
-import javax.xml.bind.ValidationEvent;
-import javax.xml.bind.ValidationEventLocator;
 import javax.xml.namespace.QName;
-import javax.xml.stream.XMLEventReader;
-import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.transform.Source;
 import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.xml.sax.SAXException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.xml.sax.SAXParseException;
 
+
 import at.gv.egiz.bku.slexceptions.SLCommandException;
 import at.gv.egiz.bku.slexceptions.SLExceptionMessages;
 import at.gv.egiz.bku.slexceptions.SLRequestException;
 import at.gv.egiz.bku.slexceptions.SLRuntimeException;
 import at.gv.egiz.bku.slexceptions.SLVersionException;
 import at.gv.egiz.bku.utils.DebugReader;
-import at.gv.egiz.slbinding.RedirectEventFilter;
-import at.gv.egiz.slbinding.RedirectUnmarshallerListener;
-import at.gv.egiz.validation.ReportingValidationEventHandler;
-
-public class SLCommandFactory {
-
-    /**
-     * Schema files required for Security Layer command validation.
-     */
-    public static final String[] SCHEMA_FILES = new String[]{
-        "at/gv/egiz/bku/slcommands/schema/xml.xsd",
-        "at/gv/egiz/bku/slcommands/schema/xmldsig-core-schema.xsd",
-        "at/gv/egiz/bku/slcommands/schema/Core-1.2.xsd",
-        "at/gv/egiz/bku/slcommands/schema/Core.20020225.xsd",
-        "at/gv/egiz/bku/slcommands/schema/Core.20020831.xsd"
-    };
-    /**
-     * Logging facility.
-     */
-    static Log log = LogFactory.getLog(SLCommandFactory.class);
-    /**
-     * The instance returned by {@link #getInstance()}.
-     */
-    private static SLCommandFactory instance;
-    /**
-     * Schema for Security Layer command validation.
-     */
-    private Schema slSchema;
-    /**
-     * The JAXBContext.
-     */
-    private JAXBContext jaxbContext;
-    /**
-     * The map of <namespaceURI>:<localName> to implementation class of the
-     * corresponding {@link SLCommand}.
-     */
-    private Map<String, Class<? extends SLCommand>> slRequestTypeMap = new HashMap<String, Class<? extends SLCommand>>();
-    
-    /**
-     * Configures the singleton instance with command implementations
-     * @param commandImplMap
-     * @throws ClassNotFoundException 
-     */
-    @SuppressWarnings("unchecked")
-    public void setCommandImpl(Map<String, String> commandImplMap) throws ClassNotFoundException {
-      ClassLoader cl = getClass().getClassLoader();
-      for (String key : commandImplMap.keySet()) {
-        Class<? extends SLCommand> impl =  (Class<? extends SLCommand>) cl.loadClass(commandImplMap.get(key));
-        log.debug("Registering sl command implementation for :"+key+ "; implementation class: "+impl.getCanonicalName());
-        slRequestTypeMap.put(key, impl);
+import at.gv.egiz.slbinding.SLUnmarshaller;
+
+public class SLCommandFactory extends SLUnmarshaller {
+  
+  private final Logger log = LoggerFactory.getLogger(SLCommandFactory.class);
+
+  private static class SLCommandFactoryInstance {
+    private static final SLCommandFactory INSTANCE = new SLCommandFactory();
+  }
+  
+  /**
+   * The mapping of a requests's qualified name to a concrete command factories.
+   */
+  private Map<QName, AbstractSLCommandFactory> slCommandFactories = new HashMap<QName, AbstractSLCommandFactory>();
+
+  public void setConcreteFactories(
+      Map<QName, AbstractSLCommandFactory> factories) {
+    if (log.isDebugEnabled()) {
+      StringBuilder sb = new StringBuilder();
+      sb.append("Registered sl command factory for");
+      for (QName qname : factories.keySet()) {
+        sb.append("\n  " + qname + " : " + factories.get(qname).getClass());
       }
+      log.debug(sb.toString());
     }
-
-    /**
-     * Register an {@link SLCommand} implementation class of a Security Layer
-     * command with the given <code>namespaceUri</code> and <code>localname</code>
-     * .
-     * 
-     * @param namespaceUri
-     *          the namespace URI of the Security Layer command
-     * @param localname
-     *          the localname of the Security Layer command
-     * @param slCommandClass
-     *          the implementation class, or <code>null</code> to deregister a
-     *          currently registered class
-     */
-    public  void setImplClass(String namespaceUri, String localname,
-      Class<? extends SLCommand> slCommandClass) {
-        if (slCommandClass != null) {
-            slRequestTypeMap.put(namespaceUri + ":" + localname, slCommandClass);
-        } else {
-            slRequestTypeMap.remove(namespaceUri + ":" + localname);
-        }
-    }
-
-    /**
-     * Returns the implementation class of an {@link SLCommand} with the given
-     * <code>name</code>, or <code>null</code> if no such class is registered.
-     * 
-     * @param name
-     *          the <code>QName</code> of the Security Layer command
-     * @return the implementation class, or <code>null</code> if no class is
-     *         registered for the given <code>name</code>
-     */
-    public Class<? extends SLCommand> getImplClass(QName name) {
-        String namespaceURI = name.getNamespaceURI();
-        String localPart = name.getLocalPart();
-        return slRequestTypeMap.get(namespaceURI + ":" + localPart);
-    }
-
-    /**
-     * Sets the schema to validate Security Layer commands with.
-     * 
-     * @param slSchema the schema to validate Security Layer commands with
-     */
-    public void setSLSchema(Schema slSchema) {
-        this.slSchema = slSchema;
-    }
-
-    /**
-     * @return the jaxbContext
-     */
-    public JAXBContext getJaxbContext() {
-        ensureJaxbContext();
-        return jaxbContext;
+    slCommandFactories = factories;
+  }
+
+  /**
+   * Get an instance of the <code>SLCommandFactory</code>.
+   */
+  public synchronized static SLCommandFactory getInstance() {
+    return SLCommandFactoryInstance.INSTANCE;
+  }
+
+  /**
+   * Private constructor used by {@link #getInstance()}.
+   */
+  private SLCommandFactory() {
+    super();
+  }
+
+  /**
+   * Creates a new <code>SLCommand</code> from the given <code>source</code> and
+   * <code>context</code>.
+   * 
+   * @param source
+   *          the <code>Source</code> to unmarshall from
+   * @return the <code>SLCommand</code> unmarshalled from the given
+   *         <code>source</code>
+   * @throws SLRequestException
+   *           if unmarshalling fails
+   * @throws SLCommandException
+   *           if command ist not supported
+   * @throws SLRuntimeException
+   *           if an unexpected error occurs configuring the unmarshaller, if
+   *           unmarshalling fails with an unexpected error or if the
+   *           corresponding <code>SLCommand</code> could not be instantiated
+   * @throws SLVersionException
+   */
+  public SLCommand createSLCommand(Source source)
+      throws SLCommandException, SLRuntimeException, SLRequestException,
+      SLVersionException {
+
+    DebugReader dr = null;
+    if (log.isTraceEnabled() && source instanceof StreamSource) {
+      StreamSource streamSource = (StreamSource) source;
+      if (streamSource.getReader() != null) {
+        dr = new DebugReader(streamSource.getReader(),
+            "SLCommand unmarshalled from:\n");
+        streamSource.setReader(dr);
+      }
     }
 
-    /**
-     * @param jaxbContext the jaxbContext to set
-     */
-    public  void setJaxbContext(JAXBContext jaxbContext) {
-        this.jaxbContext = jaxbContext;
+    Object object;
+    try {
+      object = unmarshalRequest(source);
+    } catch (SLRequestException e) {
+      throw e;
+    } finally {
+      if (dr != null) {
+        log.trace(dr.getCachedString());
+      }
     }
 
-    /**
-     * Initialize the JAXBContext.
-     */
-    private synchronized void ensureJaxbContext() {
-        if (jaxbContext == null) {
-            try {
-                // add top-level types explicitly to jaxb context, otherwise the unmarshaller won't find them.
-                // cf. http://forums.java.net/jive/thread.jspa?threadID=75778&tstart=0
-                String slImplPkg = at.gv.egiz.slbinding.impl.CreateXMLSignatureResponseType.class.getPackage().getName();
-
-                String slPkg = at.buergerkarte.namespaces.securitylayer._1.ObjectFactory.class.getPackage().getName();
-                String xmldsigPkg = org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName();
-                String cardChannelPkg = at.buergerkarte.namespaces.cardchannel.ObjectFactory.class.getPackage().getName();
-                String slPkgLegacy1_0 = at.buergerkarte.namespaces.securitylayer._20020225_.ObjectFactory.class.getPackage().getName();
-                String slPkgLegacy1_1 = at.buergerkarte.namespaces.securitylayer._20020831_.ObjectFactory.class.getPackage().getName();
-                String contextPath = slImplPkg + ":" + slPkg + ":" + xmldsigPkg + ":" + cardChannelPkg
-                    + ":" + slPkgLegacy1_0 + ":" + slPkgLegacy1_1;
-                log.debug("jaxb context path: " + contextPath);
-                setJaxbContext(JAXBContext.newInstance(contextPath));
-            } catch (JAXBException e) {
-                log.error("Failed to setup JAXBContext security layer request.", e);
-                throw new SLRuntimeException(e);
-            }
-        }
+    if (!(object instanceof JAXBElement<?>)) {
+      // invalid request
+      log.info("Invalid security layer request.\n{}", object.toString());
+      throw new SLRequestException(3002, SLExceptionMessages.EC3002_INVALID,
+          new Object[] { object.toString() });
     }
 
-    /**
-     * Initialize the security layer schema.
-     */
-    private synchronized void ensureSchema() {
-        if (slSchema == null) {
-            try {
-                SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-                ClassLoader cl = SLCommandFactory.class.getClassLoader();
-                Source[] sources = new Source[SCHEMA_FILES.length];
-                for (int i = 0; i < SCHEMA_FILES.length; i++) {
-                    String schemaFile = SCHEMA_FILES[i];
-                    URL schemaURL = cl.getResource(schemaFile);
-                    if (schemaURL == null) {
-                        throw new SLRuntimeException("Failed to load schema file " + schemaFile + ".");
-                    }
-                    log.debug("Schema location: " + schemaURL);
-                    sources[i] = new StreamSource(schemaURL.openStream());
-                }
-                Schema schema = schemaFactory.newSchema(sources);
-                log.debug("Schema successfully created.");
-                setSLSchema(schema);
-            } catch (SAXException e) {
-                log.error("Failed to load security layer schema.", e);
-                throw new SLRuntimeException("Failed to load security layer schema.", e);
-            } catch (IOException e) {
-                log.error("Failed to load security layer schema.", e);
-                throw new SLRuntimeException("Failed to load security layer schema.", e);
-            }
-
-        }
-    }
-
-    /**
-     * Get an instance of the <code>SLCommandFactory</code>.
-     */
-    public synchronized static SLCommandFactory getInstance() {
-        if (instance == null) {
-          instance = new SLCommandFactory();
-          instance.ensureJaxbContext();
-          instance.ensureSchema();
-        }
-        return instance;
+    return createSLCommand((JAXBElement<?>) object);
+
+  }
+
+  /**
+   * Creates a new <code>SLCommand</code> from the given <code>element</code>
+   * and <code>context</code>.
+   * 
+   * @param element
+   *          the request element
+   * @return the <code>SLCommand</code> for for the given <code>element</code>
+   * @throws SLCommandException
+   *           if command ist not supported
+   * @throws SLVersionException
+   */
+  public SLCommand createSLCommand(JAXBElement<?> element) throws SLCommandException, SLVersionException {
+    
+    QName qName = element.getName();
+    if (SLCommand.NAMESPACE_URI_20020831.equals(qName.getNamespaceURI())
+        || SLCommand.NAMESPACE_URI_20020225.equals(qName.getNamespaceURI())) {
+      // security layer request version not supported
+      log.info("Unsupported security layer request version {}.", qName.getNamespaceURI());
+      throw new SLVersionException(qName.getNamespaceURI());
     }
 
-    /**
-     * Private constructor used by {@link #getInstance()}.
-     */
-    private SLCommandFactory() {
+    AbstractSLCommandFactory concreteFactory = slCommandFactories.get(qName);
+    if (concreteFactory == null) {
+      // command not supported
+      log.info("Unsupported command received {}.", qName.toString());
+      throw new SLCommandException(4011,
+          SLExceptionMessages.EC4011_NOTIMPLEMENTED, new Object[] { qName
+              .toString() });
     }
 
-    /**
-     * Unmarshalls from the given <code>source</code>.
-     * 
-     * @see Unmarshaller#unmarshal(Source)
-     * 
-     * <em>Note:</em>Could replace JAXB's unmarshal-time validation engine (see commented code), however,
-     * we need a redirect filter.
-     * 
-     * @param source
-     *          the source to unmarshal from
-     * @return the object returned by {@link Unmarshaller#unmarshal(Source)}
-     * @throws SLRequestException
-     *           if unmarshalling fails
-     * @throws SLRuntimeException
-     *           if an unexpected error occurs configuring the unmarshaller or if
-     *           unmarshalling fails with an unexpected error
-     */
-    protected Object unmarshal(Source source) throws SLRuntimeException,
+    return concreteFactory.createSLCommand(element);
+    
+  }
+
+  /**
+   * Unmarshalls from the given <code>source</code>.
+   * 
+   * @see Unmarshaller#unmarshal(Source)
+   * 
+   *      <em>Note:</em>Could replace JAXB's unmarshal-time validation engine
+   *      (see commented code), however, we need a redirect filter.
+   * 
+   * @param source
+   *          the source to unmarshal from
+   * @return the object returned by {@link Unmarshaller#unmarshal(Source)}
+   * @throws SLRequestException
+   *           if unmarshalling fails
+   * @throws SLRuntimeException
+   *           if an unexpected error occurs configuring the unmarshaller or if
+   *           unmarshalling fails with an unexpected error
+   */
+  protected Object unmarshalRequest(Source source) throws SLRuntimeException,
       SLRequestException {
 
-        Object object;
-        ReportingValidationEventHandler validationEventHandler = new ReportingValidationEventHandler();
-        try {
-            
-            XMLInputFactory inputFactory = XMLInputFactory.newInstance();
-            XMLEventReader eventReader = inputFactory.createXMLEventReader(source);
-            RedirectEventFilter redirectEventFilter = new RedirectEventFilter();
-            XMLEventReader filteredReader = inputFactory.createFilteredReader(eventReader, redirectEventFilter);
-
-            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
-            unmarshaller.setListener(new RedirectUnmarshallerListener(redirectEventFilter));
-            if (slSchema != null) {
-                unmarshaller.setSchema(slSchema);
-            }
-            log.trace("Before unmarshal().");
-            unmarshaller.setEventHandler(validationEventHandler);
-            object = unmarshaller.unmarshal(filteredReader);
-            log.trace("After unmarshal().");
-        } catch (UnmarshalException e) {
-            if (log.isDebugEnabled()) {
-                log.debug("Failed to unmarshall security layer request.", e);
-            } else {
-                log.info("Failed to unmarshall security layer request." + e.getMessage());
-            }
-            if (validationEventHandler.getErrorEvent() != null) {
-            	// Validation Error
-            	ValidationEvent errorEvent = validationEventHandler.getErrorEvent();
-            	ValidationEventLocator locator = errorEvent.getLocator();
-                throw new SLRequestException(3002,
-                        SLExceptionMessages.EC3002_INVALID, new Object[]{errorEvent.getMessage()});
-            }
-            Throwable cause = e.getCause();
-            if (cause instanceof SAXParseException) {
-                throw new SLRequestException(3000,
-                  SLExceptionMessages.EC3000_UNCLASSIFIED, new Object[]{cause.getMessage()});
-            } else {
-                throw new SLRequestException(3000,
-                  SLExceptionMessages.EC3000_UNCLASSIFIED, new Object[]{e});
-            }
-        } catch (JAXBException e) {
-            // unexpected error
-            log.error("Failed to unmarshall security layer request.", e);
-            throw new SLRuntimeException(e);
-        } catch (XMLStreamException e) {
-            // unexpected error
-            log.error("Failed to unmarshall security layer request.", e);
-            throw new SLRuntimeException(e);
-        }
-
-        return object;
+    try {
+      return unmarshal(source);
+    } catch (UnmarshalException e) {
+      if (log.isDebugEnabled()) {
+        log.debug("Failed to unmarshall security layer request.", e);
+      } else {
+        log.info("Failed to unmarshall security layer request."
+            + e.getMessage());
+      }
 
+      if (e.getLinkedException() != null) {
+        throw new SLRequestException(3002, SLExceptionMessages.EC3002_INVALID,
+            new Object[] { e.getMessage() });
+      }
+      Throwable cause = e.getCause();
+      if (cause instanceof SAXParseException) {
+        throw new SLRequestException(3000,
+            SLExceptionMessages.EC3000_UNCLASSIFIED, new Object[] { cause
+                .getMessage() });
+      } else {
+        throw new SLRequestException(3000,
+            SLExceptionMessages.EC3000_UNCLASSIFIED, new Object[] { e });
+      }
+    } catch (JAXBException e) {
+      // unexpected error
+      log.error("Failed to unmarshall security layer request.", e);
+      throw new SLRuntimeException(e);
+    } catch (XMLStreamException e) {
+      // unexpected error
+      log.error("Failed to unmarshall security layer request.", e);
+      throw new SLRuntimeException(e);
     }
 
-    /**
-     * Creates a new <code>SLCommand</code> from the given <code>source</code> and
-     * <code>context</code>.
-     * 
-     * @param source
-     *          the <code>Source</code> to unmarshall from
-     * @param context
-     *          the context for the created <code>SLCommand</code>
-     * @return the <code>SLCommand</code> unmarshalled from the given
-     *         <code>source</code>
-     * @throws SLRequestException 
-     *           if unmarshalling fails
-     * @throws SLCommandException
-     *           if command ist not supported
-     * @throws SLRuntimeException
-     *           if an unexpected error occurs configuring the unmarshaller, if
-     *           unmarshalling fails with an unexpected error or if the
-     *           corresponding <code>SLCommand</code> could not be instantiated
-     * @throws SLVersionException 
-     */
-    @SuppressWarnings("unchecked")
-    public SLCommand createSLCommand(Source source, SLCommandContext context)
-      throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException {
-      
-        DebugReader dr = null;
-        if (log.isTraceEnabled() && source instanceof StreamSource) {
-          StreamSource streamSource = (StreamSource) source;
-          if (streamSource.getReader() != null) {
-            dr = new DebugReader(streamSource.getReader(), "SLCommand unmarshalled from:\n");
-            streamSource.setReader(dr);
-          }
-        }
-
-        Object object;
-        try {
-          object = unmarshal(source);
-        } catch (SLRequestException e) {
-          throw e;
-        } finally {
-          if (dr != null) {
-            log.trace(dr.getCachedString());
-          }
-        }
-        
-        if (!(object instanceof JAXBElement)) {
-            // invalid request
-            log.info("Invalid security layer request. " + object.toString());
-            throw new SLRequestException(3002, SLExceptionMessages.EC3002_INVALID,
-              new Object[]{object.toString()});
-        }
-
-        QName qName = ((JAXBElement) object).getName();
-        if (!SLCommand.NAMESPACE_URI.equals(qName.getNamespaceURI())) {
-          // security layer request version not supported
-          log.info("Unsupported security layer request version : " + qName.getNamespaceURI());
-          throw new SLVersionException(qName.getNamespaceURI());
-        }
-        
-        Class<? extends SLCommand> implClass = getImplClass(qName);
-        if (implClass == null) {
-            // command not supported
-            log.info("Unsupported command received: " + qName.toString());
-            throw new SLCommandException(4011,
-              SLExceptionMessages.EC4011_NOTIMPLEMENTED, new Object[]{qName.toString()});
-        }
-
-        
-        
-        // try to instantiate
-        SLCommand slCommand;
-        try {
-            slCommand = implClass.newInstance();
-            log.debug("SLCommand " + slCommand.getClass().toString() + " created.");
-        } catch (InstantiationException e) {
-            // unexpected error
-            log.error("Failed to instantiate security layer command implementation.",
-              e);
-            throw new SLRuntimeException(e);
-        } catch (IllegalAccessException e) {
-            // unexpected error
-            log.error("Failed to instantiate security layer command implementation.",
-              e);
-            throw new SLRuntimeException(e);
-        }
-
-        slCommand.init(context, (JAXBElement) object);
-
-        return slCommand;
-
-    }
+  }
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java
index c28288c9..30be7673 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java
@@ -36,7 +36,7 @@ public interface SLCommandInvoker {
    */
   public SLResult getResult(SLTargetContext aContext) throws SLException;
 
-  public void setCommand(at.gv.egiz.bku.slcommands.SLCommand aCmd);
+  public void setCommand(SLCommandContext commandContext, at.gv.egiz.bku.slcommands.SLCommand aCmd);
   
   /**
    * Prototype creation 
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java
index e0a375cf..e3fb863c 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java
@@ -20,15 +20,15 @@ import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import at.gv.egiz.bku.slexceptions.SLRuntimeException;
 import at.gv.egiz.marshal.MarshallerFactory;
 
 public class SLMarshallerFactory {
   
-  static Log log = LogFactory.getLog(SLMarshallerFactory.class);
+  private final Logger log = LoggerFactory.getLogger(SLMarshallerFactory.class);
 
   /**
    * The JAXBContext used for result marshaling.
@@ -98,6 +98,7 @@ public class SLMarshallerFactory {
         String cardChannelPkg = at.buergerkarte.namespaces.cardchannel.ObjectFactory.class.getPackage().getName();
         legacyContext = JAXBContext.newInstance(slPkgLegacy1_0 + ":" + slPkgLegacy1_1 + ":" + xmldsigPkg + ":" + cardChannelPkg);
       } catch (JAXBException e) {
+        Logger log = LoggerFactory.getLogger(SLMarshallerFactory.class);
         log.error("Failed to setup JAXBContext security layer request.", e);
         throw new SLRuntimeException(e);
       }
@@ -131,7 +132,7 @@ public class SLMarshallerFactory {
     try {
       return MarshallerFactory.createMarshaller(context, formattedOutput, fragment);
     } catch (JAXBException e) {
-      log.fatal("Failed to marshall error response.", e);
+      log.error("Failed to marshall error response.", e);
       throw new SLRuntimeException("Failed to marshall error response.", e);
     }
   }
@@ -164,7 +165,7 @@ public class SLMarshallerFactory {
       ensureLegacyContext();
       return MarshallerFactory.createMarshaller(legacyContext, formattedOutput, fragment);
     } catch (JAXBException e) {
-      log.fatal("Failed to marshall error response.", e);
+      log.error("Failed to marshall error response.", e);
       throw new SLRuntimeException("Failed to marshall error response.", e);
     }
   }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java
index f25a0ea4..8a8a819a 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java
@@ -19,9 +19,6 @@ package at.gv.egiz.bku.slcommands;
 import java.net.URL;
 import java.security.cert.X509Certificate;
 
-import at.gv.egiz.bku.utils.binding.Protocol;
-
-
 public class SLSourceContext {
   
   private URL sourceUrl;
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java
index 9a4536e6..4da9abb7 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java
@@ -26,8 +26,8 @@ import java.util.regex.Pattern;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import at.buergerkarte.namespaces.securitylayer._1.InfoboxAssocArrayPairType;
 import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadDataAssocArrayType;
@@ -54,7 +54,7 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl
   /**
    * Logging facility.
    */
-  private static Log log = LogFactory.getLog(AbstractAssocArrayInfobox.class);
+  private final Logger log = LoggerFactory.getLogger(AbstractAssocArrayInfobox.class);
 
   /**
    * The search string pattern.
@@ -113,7 +113,7 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl
       // TODO : build pattern
       return Collections.emptyList();
     } else {
-      log.info("Got invalid search string '" + searchString + "'");
+      log.info("Got invalid search string '{}'.", searchString);
       throw new SLCommandException(4010);
     }
     
@@ -170,14 +170,14 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl
   protected InfoboxReadResult readPairs(ReadPairs readPairs, SLCommandContext cmdCtx) throws SLCommandException {
     
     if (readPairs.isValuesAreXMLEntities() && !isValuesAreXMLEntities()) {
-      log.info("Got valuesAreXMLEntities=" + readPairs.isValuesAreXMLEntities() + " but infobox type is binary.");
+      log.info("Got valuesAreXMLEntities={} but infobox type is binary.", readPairs.isValuesAreXMLEntities());
       throw new SLCommandException(4010);
     }
     
     List<String> selectedKeys = selectKeys(readPairs.getSearchString());
     
     if (readPairs.isUserMakesUnique() && selectedKeys.size() > 1) {
-      log.info("UserMakesUnique not supported");
+      log.info("UserMakesUnique not supported.");
       // TODO: give more specific error message
       throw new SLCommandException(4010);
     }
@@ -202,7 +202,7 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl
   protected InfoboxReadResult readValue(ReadValue readValue, SLCommandContext cmdCtx) throws SLCommandException {
     
     if (readValue.isValueIsXMLEntity() && !isValuesAreXMLEntities()) {
-      log.info("Got valuesAreXMLEntities=" + readValue.isValueIsXMLEntity() + " but infobox type is binary.");
+      log.info("Got valuesAreXMLEntities={} but infobox type is binary.", readValue.isValueIsXMLEntity());
       throw new SLCommandException(4010);
     }
     
@@ -232,7 +232,7 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl
       Object value = values.get(key);
       if (areXMLEntities) {
         if (value instanceof byte[]) {
-          log.info("Got valuesAreXMLEntities=" + areXMLEntities + " but infobox type is binary.");
+          log.info("Got valuesAreXMLEntities={} but infobox type is binary.", areXMLEntities);
           throw new SLCommandException(4122);
         } else {
           XMLContentType contentType = objectFactory.createXMLContentType();
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractBinaryFileInfobox.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractBinaryFileInfobox.java
index 23394bd5..feead9e5 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractBinaryFileInfobox.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractBinaryFileInfobox.java
@@ -16,8 +16,8 @@
 */
 package at.gv.egiz.bku.slcommands.impl;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsBinaryFileType;
 import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadRequestType;
@@ -32,7 +32,7 @@ public abstract class AbstractBinaryFileInfobox extends AbstractInfoboxImpl impl
   /**
    * Logging facility.
    */
-  private static Log log = LogFactory.getLog(AbstractBinaryFileInfobox.class);
+  private final Logger log = LoggerFactory.getLogger(AbstractBinaryFileInfobox.class);
   
   /**
    * Is this infobox' content an XML entity?
@@ -57,7 +57,7 @@ public abstract class AbstractBinaryFileInfobox extends AbstractInfoboxImpl impl
     InfoboxReadParamsBinaryFileType binaryFileParameters = request.getBinaryFileParameters();
     if (binaryFileParameters != null) {
       isXMLEntity = binaryFileParameters.isContentIsXMLEntity();
-      log.debug("Got ContentIsXMLEntity=" + isXMLEntity + ".");
+      log.debug("Got ContentIsXMLEntity={}.", isXMLEntity);
     }
     
   }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandFactory.java
new file mode 100644
index 00000000..547f7eda
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandFactory.java
@@ -0,0 +1,40 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import at.gv.egiz.bku.slcommands.AbstractSLCommandFactory;
+
+public abstract class AbstractInfoboxCommandFactory extends AbstractSLCommandFactory {
+
+  protected InfoboxFactory infoboxFactory;
+  
+  /**
+   * @return the infoboxFactory
+   */
+  public InfoboxFactory getInfoboxFactory() {
+    return infoboxFactory;
+  }
+
+  /**
+   * @param infoboxFactory the infoboxFactory to set
+   */
+  public void setInfoboxFactory(InfoboxFactory infoboxFactory) {
+    this.infoboxFactory = infoboxFactory;
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandImpl.java
index 8a7edb71..8a54260f 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandImpl.java
@@ -16,7 +16,6 @@
 */
 package at.gv.egiz.bku.slcommands.impl;
 
-import at.gv.egiz.bku.slcommands.SLCommandContext;
 import at.gv.egiz.bku.slexceptions.SLCommandException;
 
 /**
@@ -32,15 +31,34 @@ public abstract class AbstractInfoboxCommandImpl<T> extends SLCommandImpl<T> {
    * The infobox implementation.
    */
   protected Infobox infobox;
+
+  /**
+   * The infobox factory.
+   */
+  protected InfoboxFactory infoboxFactory;
+  
+  /**
+   * @return the infoboxFactory
+   */
+  public InfoboxFactory getInfoboxFactory() {
+    return infoboxFactory;
+  }
+
+  /**
+   * @param infoboxFactory the infoboxFactory to set
+   */
+  public void setInfoboxFactory(InfoboxFactory infoboxFactory) {
+    this.infoboxFactory = infoboxFactory;
+  }
   
   @Override
-  public void init(SLCommandContext ctx, Object request)
+  public void init(Object request)
       throws SLCommandException {
-    super.init(ctx, request);
+    super.init(request);
     
     String infoboxIdentifier = getInfoboxIdentifier(getRequestValue());
     
-    infobox = InfoboxFactory.getInstance().createInfobox(infoboxIdentifier);
+    infobox = infoboxFactory.createInfobox(infoboxIdentifier);
   }
   
   /**
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxFactory.java
new file mode 100644
index 00000000..410d0cf8
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxFactory.java
@@ -0,0 +1,24 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+public abstract class AbstractInfoboxFactory {
+
+  public abstract Infobox createInfobox();
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxFactory.java
new file mode 100644
index 00000000..ec46f8ac
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxFactory.java
@@ -0,0 +1,27 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+public class CardChannelInfoboxFactory extends AbstractInfoboxFactory {
+
+  @Override
+  public Infobox createInfobox() {
+    return new CardChannelInfoboxImpl();
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxImpl.java
index 19b84ac7..a7851b1e 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxImpl.java
@@ -30,8 +30,8 @@ import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Unmarshaller;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import at.buergerkarte.namespaces.cardchannel.ATRType;
 import at.buergerkarte.namespaces.cardchannel.CommandAPDUType;
@@ -58,7 +58,7 @@ import at.gv.egiz.stal.ext.APDUScriptResponse.ResponseScriptElement;
 
 public class CardChannelInfoboxImpl extends AbstractBinaryFileInfobox {
   
-  private static Log log = LogFactory.getLog(CardChannelInfoboxImpl.class);
+  private final Logger log = LoggerFactory.getLogger(CardChannelInfoboxImpl.class);
   
   private static WeakHashMap<STAL, JAXBElement<ResponseType>> scriptResults = new WeakHashMap<STAL, JAXBElement<ResponseType>>();
   
@@ -149,7 +149,7 @@ public class CardChannelInfoboxImpl extends AbstractBinaryFileInfobox {
 
     
     }
-    log.info("Infobox identifier is '" + getIdentifier() + "' but XMLContent does not contain 'Script'.");
+    log.info("Infobox identifier is '{}' but XMLContent does not contain 'Script'.", getIdentifier());
     throw new SLCommandException(4010);
     
   }
@@ -217,9 +217,7 @@ public class CardChannelInfoboxImpl extends AbstractBinaryFileInfobox {
         
         ResponseAPDUType responseAPDUType = objectFactory.createResponseAPDUType();
         responseAPDUType.setSequence(BigInteger.valueOf(response.getSequence()));
-//        if (response.getRc() != 0) {
-          responseAPDUType.setRc(BigInteger.valueOf(response.getRc()));
-//        }
+        responseAPDUType.setRc(BigInteger.valueOf(response.getRc()));
         responseAPDUType.setSw(response.getSw());
         responseAPDUType.setValue(response.getApdu());
         
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxFactory.java
new file mode 100644
index 00000000..5474f249
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxFactory.java
@@ -0,0 +1,27 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+public class CertificatesInfoboxFactory extends AbstractInfoboxFactory {
+
+  @Override
+  public Infobox createInfobox() {
+    return new CertificatesInfoboxImpl();
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxImpl.java
index 0208f137..8a80e824 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxImpl.java
@@ -23,8 +23,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import at.gv.egiz.bku.slcommands.SLCommandContext;
 import at.gv.egiz.bku.slexceptions.SLCommandException;
@@ -42,7 +42,7 @@ public class CertificatesInfoboxImpl extends AbstractAssocArrayInfobox {
   /**
    * Logging facility.
    */
-  private static Log log = LogFactory.getLog(CertificatesInfoboxImpl.class);
+  private final Logger log = LoggerFactory.getLogger(CertificatesInfoboxImpl.class);
 
   /**
    * The valid keys.
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandFactory.java
new file mode 100644
index 00000000..750c2838
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandFactory.java
@@ -0,0 +1,65 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import javax.xml.bind.JAXBElement;
+
+import org.apache.commons.configuration.Configuration;
+
+import at.gv.egiz.bku.conf.MoccaConfigurationFacade;
+import at.gv.egiz.bku.slcommands.AbstractSLCommandFactory;
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slcommands.impl.xsect.DataObject;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+
+public class CreateXMLSignatureCommandFactory extends AbstractSLCommandFactory {
+
+  private ConfigurationFacade configurationFacade = new ConfigurationFacade();
+  
+  private class ConfigurationFacade implements MoccaConfigurationFacade {
+    
+    public static final String VALIDATE_HASH_DATA_INPUTS = "ValidateHashDataInputs";
+    
+    public boolean getValidateHashDataInputs() {
+      return configuration.getBoolean(VALIDATE_HASH_DATA_INPUTS, true);
+    }
+    
+  }
+  
+  @Override
+  public SLCommand createSLCommand(JAXBElement<?> element) throws SLCommandException {
+    
+    CreateXMLSignatureCommandImpl command = new CreateXMLSignatureCommandImpl();
+    command.init(element);
+    return command;
+    
+  }
+
+  /* (non-Javadoc)
+   * @see at.gv.egiz.bku.slcommands.AbstractSLCommandFactory#setConfiguration(org.apache.commons.configuration.Configuration)
+   */
+  @Override
+  public void setConfiguration(Configuration configuration) {
+    // static configuration
+    super.setConfiguration(configuration);
+    DataObject.enableHashDataInputValidation(configurationFacade.getValidateHashDataInputs());
+  }
+
+  
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java
index 01686641..d52027b2 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java
@@ -26,8 +26,8 @@ import javax.xml.crypto.MarshalException;
 import javax.xml.crypto.URIReferenceException;
 import javax.xml.crypto.dsig.XMLSignatureException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.w3c.dom.ls.DOMImplementationLS;
 import org.w3c.dom.ls.LSSerializer;
 
@@ -62,8 +62,7 @@ public class CreateXMLSignatureCommandImpl extends
   /**
    * Logging facility.
    */
-  protected static Log log = LogFactory
-      .getLog(CreateXMLSignatureCommandImpl.class);
+  private final Logger log = LoggerFactory.getLogger(CreateXMLSignatureCommandImpl.class);
 
   /**
    * The signing certificate.
@@ -79,23 +78,22 @@ public class CreateXMLSignatureCommandImpl extends
    * The to-be signed signature.
    */
   protected Signature signature;
-
-  @Override
-  public void init(SLCommandContext ctx, Object unmarshalledRequest)
-      throws SLCommandException {
-    super.init(ctx, unmarshalledRequest);
-  }
-
+  
+  /**
+   * Disable hash data input validation?
+   */
+  protected boolean disableHashdataInputValidation;
+  
   @Override
-  public void prepareXMLSignature() throws SLCommandException,
+  public void prepareXMLSignature(SLCommandContext commandContext) throws SLCommandException,
       SLRequestException {
 
     CreateXMLSignatureRequestType request = getRequestValue();
 
-    // TODO: make configurable?
+    // TODO: make configurable?
     IdValueFactory idValueFactory = new IdValueFactoryImpl();
 
-    // TODO: make configurable?
+    // TODO: make configurable?
     AlgorithmMethodFactory algorithmMethodFactory;
     try {
       algorithmMethodFactory = new AlgorithmMethodFactoryImpl(
@@ -105,21 +103,21 @@ public class CreateXMLSignatureCommandImpl extends
       throw new SLCommandException(4006);
     }
 
-    signature = new Signature(getCmdCtx().getURLDereferencerContext(),
+    signature = new Signature(commandContext.getURLDereferencer(),
         idValueFactory, algorithmMethodFactory);
 
-    // SigningTime
+    // SigningTime
     signature.setSigningTime(new Date());
 
-    // SigningCertificate
+    // SigningCertificate
     signature.setSignerCeritifcate(signingCertificate);
 
-    // SignatureInfo
+    // SignatureInfo
     if (request.getSignatureInfo() != null) {
       signature.setSignatureInfo(request.getSignatureInfo());
     }
 
-    // DataObjects
+    // DataObjects
     for (DataObjectInfoType dataObjectInfo : request.getDataObjectInfo()) {
       signature.addDataObject(dataObjectInfo);
     }
@@ -130,11 +128,12 @@ public class CreateXMLSignatureCommandImpl extends
 
   /**
    * Gets the signing certificate from STAL.
+   * @param commandContext TODO
    * 
    * @throws SLCommandException
    *           if getting the singing certificate fails
    */
-  private void getSigningCertificate() throws SLCommandException {
+  private void getSigningCertificate(SLCommandContext commandContext) throws SLCommandException {
 
     CreateXMLSignatureRequestType request = getRequestValue();
     keyboxIdentifier = request.getKeyboxIdentifier();
@@ -142,6 +141,8 @@ public class CreateXMLSignatureCommandImpl extends
     InfoboxReadRequest stalRequest = new InfoboxReadRequest();
     stalRequest.setInfoboxIdentifier(keyboxIdentifier);
 
+    STALHelper stalHelper = new STALHelper(commandContext.getSTAL());
+    
     stalHelper.transmitSTALRequest(Collections.singletonList((STALRequest) stalRequest));
     List<X509Certificate> certificates = stalHelper.getCertificatesFromResponses();
     if (certificates == null || certificates.size() != 1) {
@@ -154,15 +155,16 @@ public class CreateXMLSignatureCommandImpl extends
 
   /**
    * Signs the signature.
+   * @param commandContext TODO
    * 
    * @throws SLCommandException
    *           if signing the signature fails
    * @throws SLViewerException
    */
-  private void signXMLSignature() throws SLCommandException, SLViewerException {
+  private void signXMLSignature(SLCommandContext commandContext) throws SLCommandException, SLViewerException {
 
     try {
-      signature.sign(getCmdCtx().getSTAL(), keyboxIdentifier);
+      signature.sign(commandContext.getSTAL(), keyboxIdentifier);
     } catch (MarshalException e) {
       log.error("Failed to marshall XMLSignature.", e);
       throw new SLCommandException(4000);
@@ -181,33 +183,42 @@ public class CreateXMLSignatureCommandImpl extends
   }
 
   @Override
-  public SLResult execute() {
+  public SLResult execute(SLCommandContext commandContext) {
     try {
 
       // get certificate in order to select appropriate algorithms for hashing
-      // and signing
-      getSigningCertificate();
-
-      // prepare the XMLSignature for signing
-      prepareXMLSignature();
+      // and signing
+      log.info("Requesting signing certificate.");
+      getSigningCertificate(commandContext);
+      if (log.isDebugEnabled()) {
+        log.debug("Got signing certificate. {}", signingCertificate);
+      } else {
+        log.info("Got signing certificate.");
+      }
 
-      // sign the XMLSignature
-      signXMLSignature();
+      // prepare the XMLSignature for signing
+      log.info("Preparing XML signature.");
+      prepareXMLSignature(commandContext);
 
-      if (log.isTraceEnabled()) {
+      // sign the XMLSignature
+      log.info("Signing XML signature.");
+      signXMLSignature(commandContext);
+      if (log.isDebugEnabled()) {
 
         DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS();
         LSSerializer serializer = domImplLS.createLSSerializer();
         String debugString = serializer.writeToString(signature.getDocument());
 
-        log.trace(debugString);
+        log.debug(debugString);
 
+      } else {
+        log.info("XML signature signed.");
       }
 
       return new CreateXMLSignatureResultImpl(signature.getDocument());
 
     } catch (SLException e) {
-      return new ErrorResultImpl(e, cmdCtx.getLocale());
+      return new ErrorResultImpl(e, commandContext.getLocale());
     }
   }
 
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java
index 19df4334..51b54a37 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java
@@ -22,8 +22,8 @@ import javax.xml.bind.Marshaller;
 import javax.xml.transform.Result;
 import javax.xml.transform.Templates;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.DocumentFragment;
 import org.w3c.dom.Element;
@@ -31,6 +31,7 @@ import org.w3c.dom.Node;
 
 import at.buergerkarte.namespaces.securitylayer._1.CreateXMLSignatureResponseType;
 import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory;
+import at.gv.egiz.bku.slcommands.CreateXMLSignatureResult;
 import at.gv.egiz.bku.slcommands.SLMarshallerFactory;
 import at.gv.egiz.bku.slexceptions.SLRuntimeException;
 
@@ -39,18 +40,23 @@ import at.gv.egiz.bku.slexceptions.SLRuntimeException;
  * 
  * @author mcentner
  */
-public class CreateXMLSignatureResultImpl extends SLResultImpl {
+public class CreateXMLSignatureResultImpl extends SLResultImpl implements CreateXMLSignatureResult {
 
   /**
    * Logging facility.
    */
-  private static Log log = LogFactory.getLog(CreateXMLSignatureResultImpl.class);
+  private final Logger log = LoggerFactory.getLogger(CreateXMLSignatureResultImpl.class);
   
   /**
    * The document containing the XMLSignature.
    */
   protected Document doc;
   
+  /**
+   * The content of the CreateXMLSignatureResponse.
+   */
+  protected Element content;
+  
   /**
    * Creates a new instance of this CreateXMLSignatureResultImpl with the given
    * signature <code>document</code>.
@@ -67,6 +73,7 @@ public class CreateXMLSignatureResultImpl extends SLResultImpl {
     }
     
     this.doc = document;
+    this.content = document.getDocumentElement();
     
     marshallCreateXMLSignatureResponse();
   }
@@ -78,7 +85,7 @@ public class CreateXMLSignatureResultImpl extends SLResultImpl {
 
     ObjectFactory factory = new ObjectFactory();
     
-    CreateXMLSignatureResponseType createCreateXMLSignatureResponseType = factory.createCreateXMLSignatureResponseType();
+    at.gv.egiz.slbinding.impl.CreateXMLSignatureResponseType createCreateXMLSignatureResponseType = factory.createCreateXMLSignatureResponseType();
     JAXBElement<CreateXMLSignatureResponseType> createCreateXMLSignatureResponse = factory.createCreateXMLSignatureResponse(createCreateXMLSignatureResponseType);
 
     DocumentFragment fragment = doc.createDocumentFragment();
@@ -87,14 +94,13 @@ public class CreateXMLSignatureResultImpl extends SLResultImpl {
     try {
       marshaller.marshal(createCreateXMLSignatureResponse, fragment);
     } catch (JAXBException e) {
-      log.error("Failed to marshall 'CreateXMLSignatureResponse'", e);
+      log.error("Failed to marshall 'CreateXMLSignatureResponse'.", e);
       throw new SLRuntimeException(e);
     }
 
     Node child = fragment.getFirstChild();
     if (child instanceof Element) {
-      Node node = doc.replaceChild(child, doc.getDocumentElement());
-      child.appendChild(node);
+      child.appendChild(doc.replaceChild(child, content));
     }
     
   }
@@ -104,4 +110,9 @@ public class CreateXMLSignatureResultImpl extends SLResultImpl {
     writeTo(doc, result, templates, fragment);
   }
 
+  @Override
+  public Element getContent() {
+    return content;
+  }
+
 }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomCreateXMLSignatureResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomCreateXMLSignatureResultImpl.java
new file mode 100644
index 00000000..6d8537d6
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomCreateXMLSignatureResultImpl.java
@@ -0,0 +1,47 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import at.gv.egiz.bku.slcommands.CreateXMLSignatureResult;
+
+public class DomCreateXMLSignatureResultImpl extends DomSLResult implements
+    CreateXMLSignatureResult {
+
+  public DomCreateXMLSignatureResultImpl(Element resultElement) {
+    super(resultElement);
+  }
+
+  @Override
+  public Element getContent() {
+
+    NodeList children = resultElement.getChildNodes();
+    for (int i = 0; i < children.getLength(); i++) {
+      Node child = children.item(i);
+      if (child.getNodeType() == Node.ELEMENT_NODE) {
+        return (Element) child;
+      }
+    }
+
+    return null;
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomErrorResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomErrorResultImpl.java
new file mode 100644
index 00000000..6bb52a00
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomErrorResultImpl.java
@@ -0,0 +1,70 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import at.gv.egiz.bku.slcommands.ErrorResult;
+import at.gv.egiz.bku.slcommands.SLCommand;
+
+public class DomErrorResultImpl extends DomSLResult implements
+    ErrorResult {
+  
+  public DomErrorResultImpl(Element resultElement) {
+    super(resultElement);
+  }
+
+  @Override
+  public int getErrorCode() {
+    
+    NodeList childNodes = resultElement.getChildNodes();
+    for (int i = 0; i < childNodes.getLength(); i++) {
+      Node n = childNodes.item(i);
+      if (n.getNodeType() == Node.ELEMENT_NODE
+          && SLCommand.NAMESPACE_URI.equals(n.getNamespaceURI())
+          && "ErrorCode".equals(n.getLocalName())) {
+        try {
+          return Integer.parseInt(n.getTextContent());
+        } catch (NumberFormatException e) { }
+      }
+    }
+    
+    return 0;
+    
+  }
+
+  @Override
+  public String getInfo() {
+
+    NodeList childNodes = resultElement.getChildNodes();
+    for (int i = 0; i < childNodes.getLength(); i++) {
+      Node n = childNodes.item(i);
+      if (n.getNodeType() == Node.ELEMENT_NODE
+          && SLCommand.NAMESPACE_URI.equals(n.getNamespaceURI())
+          && "Info".equals(n.getLocalName())) {
+        return n.getTextContent();
+      }
+    }
+    
+    return null;
+    
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomInfoboxReadResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomInfoboxReadResultImpl.java
new file mode 100644
index 00000000..ce69c852
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomInfoboxReadResultImpl.java
@@ -0,0 +1,105 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import iaik.utils.Base64InputStream;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import at.gv.egiz.bku.slcommands.InfoboxReadResult;
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+import at.gv.egiz.bku.utils.StreamUtil;
+
+public class DomInfoboxReadResultImpl extends DomSLResult implements
+    InfoboxReadResult {
+
+  public DomInfoboxReadResultImpl(Element resultElement) {
+    super(resultElement);
+  }
+
+  private List<Node> getXMLContent(Node node) {
+    ArrayList<Node> content = new ArrayList<Node>();
+    NodeList xmlContent = node.getChildNodes();
+    for (int i = 0; i < xmlContent.getLength(); i++) {
+      content.add(xmlContent.item(i));
+    }
+    return content;
+  }
+  
+  private byte[] getBase64Content(Node node) {
+    String content = node.getTextContent();
+    if (content != null) {
+      try {
+        byte[] bytes = content.getBytes("ASCII");
+        Base64InputStream bis = new Base64InputStream(new ByteArrayInputStream(bytes));
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        StreamUtil.copyStream(bis, bos);
+        return bos.toByteArray();
+      } catch (UnsupportedEncodingException e) {
+        throw new SLRuntimeException(e);
+      } catch (IOException e) {
+        throw new SLRuntimeException(e);
+      }
+    } else {
+      return new byte[] {};
+    }
+  }
+  
+  private Object getBinaryFileDataContent(Node node) {
+    NodeList childNodes = node.getChildNodes();
+    for (int i = 0; i < childNodes.getLength(); i++) {
+      Node n = childNodes.item(i);
+      if (n.getNodeType() == Node.ELEMENT_NODE && SLCommand.NAMESPACE_URI.equals(n.getNamespaceURI())) {
+        if ("XMLContent".equals(n.getLocalName())) {
+          return getXMLContent(n);
+        } else if ("Base64Content".equals(n.getLocalName())) {
+          return getBase64Content(n);
+        }
+      }
+    }
+    return Collections.EMPTY_LIST;
+  }
+  
+  @Override
+  public Object getContent() {
+
+    NodeList childNodes = resultElement.getChildNodes();
+    for (int i = 0; i < childNodes.getLength(); i++) {
+      Node node = childNodes.item(i);
+      if (node.getNodeType() == Node.ELEMENT_NODE
+          && SLCommand.NAMESPACE_URI.equals(node.getNamespaceURI())
+          && "BinaryFileData".equals(node.getLocalName())) {
+        return getBinaryFileDataContent(node);
+      }
+    }
+    return Collections.EMPTY_LIST;
+    
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomSLResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomSLResult.java
new file mode 100644
index 00000000..ad81b388
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomSLResult.java
@@ -0,0 +1,41 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Templates;
+
+import org.w3c.dom.Element;
+
+
+public abstract class DomSLResult extends SLResultImpl {
+
+  protected Element resultElement;
+  
+  public DomSLResult(Element resultElement) {
+    this.resultElement= resultElement;
+  }
+  
+  @Override
+  public void writeTo(Result result, Templates templates, boolean fragment) {
+    writeTo(resultElement.getOwnerDocument(), result, templates, fragment);
+  }
+
+  
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java
index aedde238..4eb01490 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java
@@ -63,5 +63,23 @@ public class ErrorResultImpl extends SLResultImpl implements ErrorResult {
       writeErrorTo(slException, result, templates, locale, fragment);
     }
   }
+
+  @Override
+  public int getErrorCode() {
+    if (slException != null) {
+      return slException.getErrorCode();
+    } else {
+      return -1;
+    }
+  }
+
+  @Override
+  public String getInfo() {
+    if (slException != null) {
+      return slException.getLocalizedMessage(locale);
+    } else {
+      return null;
+    }
+  }
   
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandFactory.java
new file mode 100644
index 00000000..2a29b8da
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandFactory.java
@@ -0,0 +1,37 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import javax.xml.bind.JAXBElement;
+
+import at.gv.egiz.bku.slcommands.AbstractSLCommandFactory;
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+
+public class GetStatusCommandFactory extends AbstractSLCommandFactory {
+
+  @Override
+  public SLCommand createSLCommand(JAXBElement<?> element) throws SLCommandException {
+    
+    GetStatusCommandImpl command = new GetStatusCommandImpl();
+    command.init(element);
+    return command;
+    
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java
index 0c2b96f9..d58141a1 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java
@@ -19,6 +19,7 @@ package at.gv.egiz.bku.slcommands.impl;
 
 import at.buergerkarte.namespaces.securitylayer._1.GetStatusRequestType;
 import at.gv.egiz.bku.slcommands.GetStatusCommand;
+import at.gv.egiz.bku.slcommands.SLCommandContext;
 import at.gv.egiz.bku.slcommands.SLResult;
 import at.gv.egiz.bku.slexceptions.SLCommandException;
 import at.gv.egiz.stal.ErrorResponse;
@@ -28,8 +29,8 @@ import at.gv.egiz.stal.StatusRequest;
 import at.gv.egiz.stal.StatusResponse;
 import java.util.Collections;
 import java.util.List;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  *
@@ -37,7 +38,7 @@ import org.apache.commons.logging.LogFactory;
  */
 public class GetStatusCommandImpl extends SLCommandImpl<GetStatusRequestType> implements GetStatusCommand {
 
-  protected static Log log = LogFactory.getLog(GetStatusCommandImpl.class);
+  protected final Logger log = LoggerFactory.getLogger(GetStatusCommandImpl.class);
 
   @Override
   public String getName() {
@@ -45,16 +46,15 @@ public class GetStatusCommandImpl extends SLCommandImpl<GetStatusRequestType> im
   }
 
   @Override
-  public SLResult execute() {
+  public SLResult execute(SLCommandContext commandContext) {
 
     //ignore maxDelay and TokenStatus
-//    GetStatusRequestType req = getRequestValue();
 
-    log.debug("execute GetStatusRequest");
+    log.debug("Execute GetStatusRequest.");
 
     StatusRequest stalRequest = new StatusRequest();
 
-    STAL stal = cmdCtx.getSTAL();
+    STAL stal = commandContext.getSTAL();
 
     List<STALResponse> responses = stal.handleRequest(Collections.singletonList(stalRequest));
     
@@ -62,16 +62,16 @@ public class GetStatusCommandImpl extends SLCommandImpl<GetStatusRequestType> im
       STALResponse stalResponse = responses.get(0);
       if (stalResponse instanceof StatusResponse) {
         boolean ready = ((StatusResponse) stalResponse).isCardReady();
-        log.trace("received status response cardReady: " + ready);
+        log.trace("Received status response cardReady: {}.", ready);
         return new GetStatusResultImpl(ready);
       } else if (stalResponse instanceof ErrorResponse) {
-        log.debug("received error response");
+        log.debug("Received error response.");
         SLCommandException ex = new SLCommandException(((ErrorResponse) stalResponse).getErrorCode());
-        return new ErrorResultImpl(ex, cmdCtx.getLocale());
+        return new ErrorResultImpl(ex, commandContext.getLocale());
       }
     }
-    log.error("received unexpected responses");
-    return new ErrorResultImpl(new SLCommandException(4000), cmdCtx.getLocale());
+    log.error("Received unexpected responses.");
+    return new ErrorResultImpl(new SLCommandException(4000), commandContext.getLocale());
 
   }
 }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxFactory.java
new file mode 100644
index 00000000..c19f52ac
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxFactory.java
@@ -0,0 +1,48 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import at.gv.egiz.idlink.IdentityLinkTransformer;
+
+public class IdentityLinkInfoboxFactory extends AbstractInfoboxFactory {
+
+  private IdentityLinkTransformer identityLinkTransformer;
+  
+  @Override
+  public Infobox createInfobox() {
+    IdentityLinkInfoboxImpl infoboxImpl = new IdentityLinkInfoboxImpl();
+    infoboxImpl.setIdentityLinkTransformer(identityLinkTransformer);
+    return infoboxImpl;
+  }
+
+  /**
+   * @return the identityLinkTransformer
+   */
+  public IdentityLinkTransformer getIdentityLinkTransformer() {
+    return identityLinkTransformer;
+  }
+
+  /**
+   * @param identityLinkTransformer the identityLinkTransformer to set
+   */
+  public void setIdentityLinkTransformer(
+      IdentityLinkTransformer identityLinkTransformer) {
+    this.identityLinkTransformer = identityLinkTransformer;
+  }
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java
index 160e9589..ec873e20 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java
@@ -37,8 +37,8 @@ import javax.xml.transform.dom.DOMResult;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 
@@ -68,13 +68,30 @@ public class IdentityLinkInfoboxImpl extends AbstractBinaryFileInfobox {
   /**
    * Logging facility.
    */
-  private static Log log = LogFactory.getLog(IdentityLinkInfoboxImpl.class);
+  private final Logger log = LoggerFactory.getLogger(IdentityLinkInfoboxImpl.class);
 
   /**
    * The box specific parameter <code>IdentityLinkDomainIdentifier</code>.
    */
   public static final String BOX_SPECIFIC_PARAMETER_IDENTITY_LINK_DOMAIN_IDENTIFIER = "IdentityLinkDomainIdentifier";
   
+  private IdentityLinkTransformer identityLinkTransformer;
+  
+  /**
+   * @return the identityLinkTransformer
+   */
+  public IdentityLinkTransformer getIdentityLinkTransformer() {
+    return identityLinkTransformer;
+  }
+
+  /**
+   * @param identityLinkTransformer the identityLinkTransformer to set
+   */
+  public void setIdentityLinkTransformer(
+      IdentityLinkTransformer identityLinkTransformer) {
+    this.identityLinkTransformer = identityLinkTransformer;
+  }
+
   /**
    * The value of the box specific parameter <code>IdentityLinkDomainIdentifier</code>.
    */
@@ -147,7 +164,6 @@ public class IdentityLinkInfoboxImpl extends AbstractBinaryFileInfobox {
     JAXBElement<CompressedIdentityLinkType> compressedIdentityLink = idLinkFactory
         .createCompressedIdentityLink(identityLink, certificates, getDomainIdentifier());
 
-    IdentityLinkTransformer identityLinkTransformer = IdentityLinkTransformer.getInstance();
     String issuerTemplate = identityLink.getIssuerTemplate();
     
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
@@ -262,12 +278,12 @@ public class IdentityLinkInfoboxImpl extends AbstractBinaryFileInfobox {
             Transformer transformer = transformerFactory.newTransformer();
             transformer.transform(xmlSource, new StreamResult(resultBytes));
           } catch (TransformerConfigurationException e) {
-            log.error(e);
+            log.error("Failed to transform identity link.", e);
             throw new SLCommandException(4000,
                 SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED,
                 new Object[] { issuerTemplate });
           } catch (TransformerException e) {
-            log.error(e);
+            log.error("Failed to transform identity link.", e);
             throw new SLCommandException(4000,
                 SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED,
                 new Object[] { issuerTemplate });
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxFactory.java
index e9736f6d..5ba06ac4 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxFactory.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxFactory.java
@@ -17,10 +17,9 @@
 package at.gv.egiz.bku.slcommands.impl;
 
 import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import at.gv.egiz.bku.slexceptions.SLCommandException;
 import at.gv.egiz.bku.slexceptions.SLExceptionMessages;
@@ -36,71 +35,27 @@ public class InfoboxFactory {
   /**
    * Logging facility.
    */
-  private static Log log = LogFactory.getLog(InfoboxFactory.class);
+  private final Logger log = LoggerFactory.getLogger(InfoboxFactory.class);
   
   /**
-   * The singleton instance of this InfoboxFactory.
+   * The mapping of Infobox name to concrete Infobox factory.
    */
-  private static InfoboxFactory instance;
-
-  /**
-   * @return an instance of this InfoboxFactory
-   */
-  public synchronized static InfoboxFactory getInstance() {
-    if (instance == null) {
-      instance = new InfoboxFactory();
-    }
-    return instance;
-  }
- 
-  /**
-   * The mapping of infobox identifier to implementation class.
-   */
-  private HashMap<String, Class<? extends Infobox>> implementations;
-
-  /**
-   * Private constructor.
-   */
-  private InfoboxFactory() {
-  }
-
-  /**
-   * Sets the mapping of infobox identifier to implementation class name.
-   * 
-   * @param infoboxImplMap
-   *          a mapping of infobox identifiers to implementation class names
-   * 
-   * @throws ClassNotFoundException
-   *           if implementation class is not an instance of {@link Infobox}
-   */
-  @SuppressWarnings("unchecked")
-  public void setInfoboxImpl(Map<String, String> infoboxImplMap) throws ClassNotFoundException {
-    HashMap<String, Class<? extends Infobox>> implMap = new HashMap<String, Class<? extends Infobox>>();
-    ClassLoader cl = getClass().getClassLoader();
-    for (String key : infoboxImplMap.keySet()) {
-      Class<? extends Infobox> impl = (Class<? extends Infobox>) cl.loadClass(infoboxImplMap.get(key));
-      log.debug("Registering infobox '" + key + "' implementation '" + impl.getCanonicalName() + "'.");
-      implMap.put(key, impl);
-    }
-    implementations = implMap;
-  }
-
+  private HashMap<String, AbstractInfoboxFactory> infoboxFactories = new HashMap<String, AbstractInfoboxFactory>();
+  
   /**
-   * Returns the configured implementation class for the given
-   * <code>infoboxIdentifier</code>.
-   * 
-   * @param infoboxIdentifier
-   *          the infobox identifier
-   * 
-   * @return the implementation class for the given infobox identifier or
-   *         <code>null</code> if there is no implementation class configured
+   * @param infoboxFactories the infoboxFactories to set
    */
-  public Class<? extends Infobox> getImplClass(String infoboxIdentifier) {
-    if (implementations != null) {
-      return implementations.get(infoboxIdentifier);
-    } else {
-      return null;
+  public void setInfoboxFactories(
+      HashMap<String, AbstractInfoboxFactory> factories) {
+    if (log.isDebugEnabled()) {
+      StringBuilder sb = new StringBuilder();
+      sb.append("Registered infobox factories for");
+      for (String name : factories.keySet()) {
+        sb.append("\n  " + name + " : " + factories.get(name).getClass());
+      }
+      log.debug(sb.toString());
     }
+    this.infoboxFactories = factories;
   }
 
   /**
@@ -119,31 +74,15 @@ public class InfoboxFactory {
    */
   public Infobox createInfobox(String infoboxIdentifier) throws SLCommandException, SLRuntimeException {
     
-    Class<? extends Infobox> implClass = getImplClass(infoboxIdentifier);
-    if (implClass == null) {
-      // infobox not supported
-      log.info("Unsupported infobox '" + infoboxIdentifier + ".");
+    AbstractInfoboxFactory factory = infoboxFactories.get(infoboxIdentifier);
+    if (factory == null) {
+      log.info("Unsupported infobox '{}'.", infoboxIdentifier);
       throw new SLCommandException(4002,
           SLExceptionMessages.EC4002_INFOBOX_UNKNOWN,
           new Object[] { infoboxIdentifier });
     }
     
-    // try to instantiate
-    Infobox infobox;
-    try {
-      infobox = implClass.newInstance();
-      log.debug("Infobox '" + infobox.getIdentifier() + "' created.");
-    } catch (InstantiationException e) {
-      // unexpected error
-      log.error("Failed to instantiate infobox implementation.", e);
-      throw new SLRuntimeException(e);
-    } catch (IllegalAccessException e) {
-      // unexpected error
-      log.error("Failed to instantiate infobox implementation.", e);
-      throw new SLRuntimeException(e);
-    }
-    
-    return infobox;
+    return factory.createInfobox();
     
   }
   
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandFactory.java
new file mode 100644
index 00000000..a9ba28e4
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandFactory.java
@@ -0,0 +1,37 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import javax.xml.bind.JAXBElement;
+
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+
+public class InfoboxReadCommandFactory extends AbstractInfoboxCommandFactory {
+
+  @Override
+  public SLCommand createSLCommand(JAXBElement<?> element) throws SLCommandException {
+    
+    InfoboxReadCommandImpl command = new InfoboxReadCommandImpl();
+    command.setInfoboxFactory(infoboxFactory);
+    command.init(element);
+    return command;
+    
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java
index 693f444f..736e7cbb 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java
@@ -14,50 +14,50 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-package at.gv.egiz.bku.slcommands.impl;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+package at.gv.egiz.bku.slcommands.impl;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadRequestType;
 import at.gv.egiz.bku.slcommands.InfoboxReadCommand;
 import at.gv.egiz.bku.slcommands.SLCommandContext;
 import at.gv.egiz.bku.slcommands.SLResult;
 import at.gv.egiz.bku.slexceptions.SLCommandException;
-
-/**
- * This class implements the security layer command
- * <code>InfoboxReadRequest</code>.
- * <p>
- * <b>NOTE:</b> Currently the only supported infobox identifier is '
- * <code>IdentityLink</code>'.
- * </p>
- * 
- * @author mcentner
- */
-public class InfoboxReadCommandImpl extends AbstractInfoboxCommandImpl<InfoboxReadRequestType> implements
-    InfoboxReadCommand {
-  
-  /**
-   * Logging facility.
-   */
-  protected static Log log = LogFactory.getLog(InfoboxReadCommandImpl.class);
+
+/**
+ * This class implements the security layer command
+ * <code>InfoboxReadRequest</code>.
+ * <p>
+ * <b>NOTE:</b> Currently the only supported infobox identifier is '
+ * <code>IdentityLink</code>'.
+ * </p>
+ * 
+ * @author mcentner
+ */
+public class InfoboxReadCommandImpl extends AbstractInfoboxCommandImpl<InfoboxReadRequestType> implements
+    InfoboxReadCommand {
+  
+  /**
+   * Logging facility.
+   */
+  protected final Logger log = LoggerFactory.getLogger(InfoboxReadCommandImpl.class);
   
-  @Override
-  public String getName() {
-    return "InfoboxReadRequest";
-  }
-
+  @Override
+  public String getName() {
+    return "InfoboxReadRequest";
+  }
+
   @Override
   protected String getInfoboxIdentifier(InfoboxReadRequestType request) {
     return request.getInfoboxIdentifier();
   }
 
-  @Override
-  public void init(SLCommandContext ctx, Object request) throws SLCommandException {
-    super.init(ctx, request);
-    
-    InfoboxReadRequestType req = getRequestValue();
+  @Override
+  public void init(Object request) throws SLCommandException {
+    super.init(request);
+    
+    InfoboxReadRequestType req = getRequestValue();
     
     if (req.getAssocArrayParameters() != null && 
         !(infobox instanceof AssocArrayInfobox)) {
@@ -70,20 +70,20 @@ public class InfoboxReadCommandImpl extends AbstractInfoboxCommandImpl<InfoboxRe
       log.info("Got BinaryFileParameters but Infobox type is not BinaryFile.");
       throw new SLCommandException(4010);
     }
-    
-  }
-
-  @Override
-  public SLResult execute() {
+    
+  }
+
+  @Override
+  public SLResult execute(SLCommandContext commandContext) {
     
     try {
-      return infobox.read(getRequestValue(), getCmdCtx());
+      return infobox.read(getRequestValue(), commandContext);
     } catch (SLCommandException e) {
-      return new ErrorResultImpl(e, getCmdCtx().getLocale());
+      return new ErrorResultImpl(e, commandContext.getLocale());
     }
     
-  }
-
+  }
+
   @Override
   public String getIdentityLinkDomainId() {
     if (infobox instanceof IdentityLinkInfoboxImpl) {
@@ -93,4 +93,4 @@ public class InfoboxReadCommandImpl extends AbstractInfoboxCommandImpl<InfoboxRe
     }
   }
 
-}
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java
index 422b424f..ddbbcadc 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java
@@ -16,6 +16,9 @@
 */
 package at.gv.egiz.bku.slcommands.impl;
 
+import java.util.ArrayList;
+import java.util.Collections;
+
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
@@ -25,8 +28,8 @@ import javax.xml.transform.Result;
 import javax.xml.transform.Templates;
 import javax.xml.transform.dom.DOMResult;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -51,12 +54,17 @@ public class InfoboxReadResultFileImpl extends SLResultImpl implements
   /**
    * Logging facility.
    */
-  protected static Log log = LogFactory.getLog(InfoboxReadResultFileImpl.class);
+  protected final Logger log = LoggerFactory.getLogger(InfoboxReadResultFileImpl.class);
 
   /**
    * The XML document containing the infobox content.
    */
   protected Document xmlDocument;
+  
+  /**
+   * Binary content of the infobox (may be <code>null</code>). 
+   */
+  protected byte[] binaryContent;
 
   /**
    * Creates the response document from the given <code>binaryContent</code>.
@@ -147,14 +155,34 @@ public class InfoboxReadResultFileImpl extends SLResultImpl implements
    * @param resultBytes
    */
   public void setResultBytes(byte[] resultBytes) {
-    
-    xmlDocument = createResponseDocument(resultBytes, false);
-    
+    this.binaryContent = resultBytes;
   }
   
   @Override
   public void writeTo(Result result, Templates templates, boolean fragment) {
+    if (xmlDocument == null) {
+      xmlDocument = createResponseDocument(binaryContent, false);
+    }
     writeTo(xmlDocument, result, templates, fragment);
   }
 
+  @Override
+  public Object getContent() {
+    if (xmlDocument != null) {
+      NodeList nodes = xmlDocument.getElementsByTagNameNS(SLCommand.NAMESPACE_URI, "XMLContent");
+      if (nodes.getLength() > 0) {
+        NodeList children = nodes.item(0).getChildNodes();
+        ArrayList<Node> content = new ArrayList<Node>();
+        for (int i = 0; i < children.getLength(); i++) {
+          content.add(children.item(i));
+        }
+        return Collections.unmodifiableList(content);
+      } else {
+        return null;
+      }
+    } else {
+      return binaryContent;
+    }
+  }
+
 }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java
index 271ec955..3be6c8f8 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java
@@ -61,4 +61,22 @@ public class InfoboxReadResultImpl extends SLResultImpl implements InfoboxReadRe
     writeTo(response, result, templates, fragment);
   }
 
+  @Override
+  public Object getContent() {
+    if (infoboxReadResponse != null) {
+      if (infoboxReadResponse.getAssocArrayData() != null) {
+        return infoboxReadResponse.getAssocArrayData();
+      } else {
+        Base64XMLContentType binaryFileData = infoboxReadResponse.getBinaryFileData();
+        if (binaryFileData.getBase64Content() != null) {
+          return binaryFileData.getBase64Content();
+        } else {
+          return binaryFileData.getXMLContent().getContent();
+        }
+      }
+    } else {
+      return null;
+    }
+  }
+
 }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandFactory.java
new file mode 100644
index 00000000..0d421b2f
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandFactory.java
@@ -0,0 +1,37 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import javax.xml.bind.JAXBElement;
+
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+
+public class InfoboxUpdateCommandFactory extends AbstractInfoboxCommandFactory {
+
+  @Override
+  public SLCommand createSLCommand(JAXBElement<?> element) throws SLCommandException {
+    
+    InfoboxUpdateCommandImpl command = new InfoboxUpdateCommandImpl();
+    command.setInfoboxFactory(infoboxFactory);
+    command.init(element);
+    return command;
+    
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandImpl.java
index 1cdeda94..100be13b 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandImpl.java
@@ -16,8 +16,8 @@
 */
 package at.gv.egiz.bku.slcommands.impl;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import at.buergerkarte.namespaces.securitylayer._1.InfoboxUpdateRequestType;
 import at.gv.egiz.bku.slcommands.InfoboxUpdateCommand;
@@ -28,7 +28,7 @@ import at.gv.egiz.bku.slexceptions.SLCommandException;
 public class InfoboxUpdateCommandImpl extends
     AbstractInfoboxCommandImpl<InfoboxUpdateRequestType> implements InfoboxUpdateCommand {
   
-  private static Log log = LogFactory.getLog(InfoboxUpdateCommandImpl.class);
+  private final Logger log = LoggerFactory.getLogger(InfoboxUpdateCommandImpl.class);
 
   @Override
   public String getName() {
@@ -41,8 +41,8 @@ public class InfoboxUpdateCommandImpl extends
   }
 
   @Override
-  public void init(SLCommandContext ctx, Object request) throws SLCommandException {
-    super.init(ctx, request);
+  public void init(Object request) throws SLCommandException {
+    super.init(request);
     
     InfoboxUpdateRequestType req = getRequestValue();
     
@@ -61,12 +61,12 @@ public class InfoboxUpdateCommandImpl extends
   }
 
   @Override
-  public SLResult execute() {
+  public SLResult execute(SLCommandContext commandContext) {
     
     try {
-      return infobox.update(getRequestValue(), getCmdCtx());
+      return infobox.update(getRequestValue(), commandContext);
     } catch (SLCommandException e) {
-      return new ErrorResultImpl(e, getCmdCtx().getLocale());
+      return new ErrorResultImpl(e, commandContext.getLocale());
     }
     
   }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandFactory.java
new file mode 100644
index 00000000..4b5ba381
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandFactory.java
@@ -0,0 +1,37 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import javax.xml.bind.JAXBElement;
+
+import at.gv.egiz.bku.slcommands.AbstractSLCommandFactory;
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+
+public class NullOperationCommandFactory extends AbstractSLCommandFactory {
+
+  @Override
+  public SLCommand createSLCommand(JAXBElement<?> element) throws SLCommandException {
+    
+    NullOperationCommandImpl command = new NullOperationCommandImpl();
+    command.init(element);
+    return command;
+    
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandImpl.java
index 1b6fb237..4d326157 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandImpl.java
@@ -19,6 +19,7 @@ package at.gv.egiz.bku.slcommands.impl;
 import at.buergerkarte.namespaces.securitylayer._1.NullOperationRequestType;
 import at.gv.egiz.bku.slcommands.NullOperationCommand;
 import at.gv.egiz.bku.slcommands.NullOperationResult;
+import at.gv.egiz.bku.slcommands.SLCommandContext;
 import at.gv.egiz.bku.slcommands.SLResult;
 
 /**
@@ -31,7 +32,7 @@ public class NullOperationCommandImpl extends SLCommandImpl<NullOperationRequest
   protected static NullOperationResult RESULT = new NullOperationResultImpl();
   
   @Override
-  public SLResult execute() {
+  public SLResult execute(SLCommandContext commandContext) {
     return RESULT;
   }
 
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLCommandImpl.java
index ed055b69..41783c34 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLCommandImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLCommandImpl.java
@@ -19,7 +19,6 @@ package at.gv.egiz.bku.slcommands.impl;
 import javax.xml.bind.JAXBElement;
 
 import at.gv.egiz.bku.slcommands.SLCommand;
-import at.gv.egiz.bku.slcommands.SLCommandContext;
 import at.gv.egiz.bku.slexceptions.SLCommandException;
 
 /**
@@ -33,16 +32,6 @@ import at.gv.egiz.bku.slexceptions.SLCommandException;
  */
 public abstract class SLCommandImpl<T> implements SLCommand {
 
-  /**
-   * The <code>SLCommandContext</code> for this <code>SLCommand</code>.
-   */
-  protected SLCommandContext cmdCtx;
-  
-  /**
-   * The STAL helper.
-   */
-  protected STALHelper stalHelper;
-
   /**
    * The request element of this command.
    */
@@ -50,14 +39,9 @@ public abstract class SLCommandImpl<T> implements SLCommand {
 
   @SuppressWarnings("unchecked")
   @Override
-  public void init(SLCommandContext ctx, Object request)
+  public void init(Object request)
       throws SLCommandException {
-
     this.request = (JAXBElement<T>) request;
-
-    this.cmdCtx = ctx;
-    stalHelper = new STALHelper(cmdCtx.getSTAL());
-
   }
 
   /**
@@ -70,12 +54,13 @@ public abstract class SLCommandImpl<T> implements SLCommand {
    */
   protected T getRequestValue() {
     return request.getValue();
-  }
+  }
+
+  /**
+   * @return the request
+   */
+  public JAXBElement<T> getRequest() {
+    return request;
+  }
 
-  /**
-   * @return the corresponding <code>SLCommandContext</code>
-   */
-  protected SLCommandContext getCmdCtx() {
-    return cmdCtx;
-  }
 }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java
index 0077b7b2..1a2dcb52 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java
@@ -37,8 +37,8 @@ import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
 import javax.xml.transform.stream.StreamResult;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.w3c.dom.Node;
 
 import at.buergerkarte.namespaces.securitylayer._1.ErrorResponseType;
@@ -64,7 +64,7 @@ public abstract class SLResultImpl implements SLResult {
   /**
    * Logging facility.
    */
-  private static Log log = LogFactory.getLog(SLResult.class);
+  private final Logger log = LoggerFactory.getLogger(SLResult.class);
 
   /**
    * The security layer result type (default = XML).
@@ -158,21 +158,21 @@ public abstract class SLResultImpl implements SLResult {
         marshaller.marshal(response, result);
       }
     } catch (JAXBException e) {
-      log.info("Failed to marshall " + response.getName() + " result." , e);
+      log.info("Failed to marshall {} result.", response.getName(), e);
       SLCommandException commandException = new SLCommandException(4000);
       writeErrorTo(commandException, result, templates, fragment);
     }
     
     if (ds != null) {
       try {
-        log.trace("Marshalled result:\n" + new String(ds.getBufferedBytes(), "UTF-8"));
+        log.trace("Marshalled result:\n{}", new String(ds.getBufferedBytes(), "UTF-8"));
       } catch (UnsupportedEncodingException e) {
         log.trace(e.getMessage());
       }
     }
     
     if (dw != null) {
-      log.trace("Marshalled result:\n" + dw.getBufferedString());
+      log.trace("Marshalled result:\n{}", dw.getBufferedString());
     }
     
   }
@@ -226,14 +226,14 @@ public abstract class SLResultImpl implements SLResult {
 
     if (ds != null) {
       try {
-        log.trace("Marshalled result:\n" + new String(ds.getBufferedBytes(), "UTF-8"));
+        log.trace("Marshalled result:\n{}", new String(ds.getBufferedBytes(), "UTF-8"));
       } catch (UnsupportedEncodingException e) {
         log.trace(e.getMessage());
       }
     }
     
     if (dw != null) {
-      log.trace("Marshalled result:\n" + dw.getBufferedString());
+      log.trace("Marshalled result:\n{}", dw.getBufferedString());
     }
 
   }
@@ -288,7 +288,7 @@ public abstract class SLResultImpl implements SLResult {
         marshaller.marshal(response, result);
       }
     } catch (JAXBException e) {
-      log.fatal("Failed to marshall error result." , e);
+      log.error("Failed to marshall error result." , e);
       throw new SLRuntimeException("Failed to marshall error result.");
     }
     
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java
index e903c608..fd20acb4 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java
@@ -22,11 +22,8 @@ import iaik.utils.Base64OutputStream;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
-import java.io.StringWriter;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
@@ -35,8 +32,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import at.gv.egiz.bku.slexceptions.SLCommandException;
 import at.gv.egiz.bku.slexceptions.SLExceptionMessages;
@@ -59,7 +56,7 @@ public class STALHelper {
   /**
    * Logging facility.
    */
-  private static Log log = LogFactory.getLog(STALHelper.class);
+  private final Logger log = LoggerFactory.getLogger(STALHelper.class);
   
   /**
    * The STAL implementation.
@@ -95,11 +92,11 @@ public class STALHelper {
    public void transmitSTALRequest(List<? extends STALRequest> stalRequests) throws SLCommandException {
     List<STALResponse> responses = stal.handleRequest(stalRequests);
     if (responses == null) {
-      Log log = LogFactory.getLog(this.getClass());
+      Logger log = LoggerFactory.getLogger(this.getClass());
       log.info("Received no responses from STAL.");
       throw new SLCommandException(4000);
     } else if (responses.size() != stalRequests.size()) {
-      Log log = LogFactory.getLog(this.getClass());
+      Logger log = LoggerFactory.getLogger(this.getClass());
       log.info("Received invalid count of responses from STAL. Expected "
           + stalRequests.size() + ", but got " + responses.size() + ".");
       // throw new SLCommandException(4000);
@@ -144,7 +141,7 @@ public class STALHelper {
     }
 
     if (!(responseClass.isAssignableFrom(response.getClass()))) {
-      Log log = LogFactory.getLog(this.getClass());
+      Logger log = LoggerFactory.getLogger(this.getClass());
       log.info("Received " + response.getClass() + " from STAL but expected "
           + responseClass);
       throw new SLCommandException(4000);
@@ -195,7 +192,7 @@ public class STALHelper {
           } catch (IOException e1) {
             log.info("Failed to decode certificate.", e);
           }
-          log.debug("Failed to decode certificate.\n" + certDump.toString(), e);
+          log.debug("Failed to decode certificate.\n{}", certDump.toString(), e);
         } else {
           log.info("Failed to decode certificate.", e);
         }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxFactory.java
new file mode 100644
index 00000000..ea892ea9
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxFactory.java
@@ -0,0 +1,27 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl;
+
+public class SVPersonendatenInfoboxFactory extends AbstractInfoboxFactory {
+
+  @Override
+  public Infobox createInfobox() {
+    return new SVPersonendatenInfoboxImpl();
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImpl.java
index 7e204632..4a94b627 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImpl.java
@@ -44,8 +44,8 @@ import java.util.TimeZone;
 import javax.xml.datatype.DatatypeFactory;
 import javax.xml.datatype.XMLGregorianCalendar;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import at.buergerkarte.namespaces.cardchannel.AttributeList;
 import at.buergerkarte.namespaces.cardchannel.AttributeType;
@@ -68,7 +68,7 @@ public class SVPersonendatenInfoboxImpl extends AbstractAssocArrayInfobox {
   /**
    * Logging facility.
    */
-  private static Log log = LogFactory.getLog(SVPersonendatenInfoboxImpl.class);
+  private final Logger log = LoggerFactory.getLogger(SVPersonendatenInfoboxImpl.class);
 
   public static final String EHIC = "EHIC";
   
@@ -145,7 +145,7 @@ public class SVPersonendatenInfoboxImpl extends AbstractAssocArrayInfobox {
           
         }
       } catch (CodingException e) {
-        log.info("Failed to decode '" + getIdentifier() + "' infobox.", e);
+        log.info("Failed to decode '{}' infobox.", getIdentifier(), e);
         throw new SLCommandException(4000,
             SLExceptionMessages.EC4000_UNCLASSIFIED_INFOBOX_INVALID,
             new Object[] { "IdentityLink" });
@@ -256,6 +256,8 @@ public class SVPersonendatenInfoboxImpl extends AbstractAssocArrayInfobox {
   
   private static void setAttributeValue(AttributeType attributeType, ASN1Object value) {
     
+    Logger log = LoggerFactory.getLogger(SVPersonendatenInfoboxImpl.class);
+    
     if (value.isA(ASN.OCTET_STRING)) {
       
       try {
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java
index 8391e450..f1219a6c 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java
@@ -165,8 +165,7 @@ public class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory {
   public SignatureMethod createSignatureMethod(SignatureContext signatureContext)
       throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
 
-    return signatureContext.getSignatureFactory().newSignatureMethod(
-        signatureAlgorithmURI, signatureMethodParameterSpec);
+    return new STALSignatureMethod(signatureAlgorithmURI, signatureMethodParameterSpec);
   }
 
 }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java
index 2cae41d6..a3f913de 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java
@@ -20,11 +20,13 @@ import iaik.xml.crypto.dom.DOMCryptoContext;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.SequenceInputStream;
 import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
+import java.net.URI;
 import java.net.URISyntaxException;
 import java.nio.charset.Charset;
 import java.security.InvalidAlgorithmParameterException;
@@ -36,6 +38,9 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
 import javax.xml.crypto.MarshalException;
 import javax.xml.crypto.dom.DOMStructure;
 import javax.xml.crypto.dsig.CanonicalizationMethod;
@@ -46,15 +51,17 @@ import javax.xml.crypto.dsig.XMLObject;
 import javax.xml.crypto.dsig.spec.TransformParameterSpec;
 import javax.xml.crypto.dsig.spec.XPathFilter2ParameterSpec;
 import javax.xml.crypto.dsig.spec.XPathType;
+import javax.xml.namespace.QName;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.w3c.dom.DOMConfiguration;
 import org.w3c.dom.DOMException;
 import org.w3c.dom.Document;
 import org.w3c.dom.DocumentFragment;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 import org.w3c.dom.Text;
 import org.w3c.dom.bootstrap.DOMImplementationRegistry;
 import org.w3c.dom.ls.DOMImplementationLS;
@@ -70,6 +77,7 @@ import at.buergerkarte.namespaces.securitylayer._1.MetaInfoType;
 import at.buergerkarte.namespaces.securitylayer._1.TransformsInfoType;
 import at.gv.egiz.bku.binding.HttpUtil;
 import at.gv.egiz.bku.gui.viewer.MimeTypes;
+import at.gv.egiz.bku.slcommands.SLMarshallerFactory;
 import at.gv.egiz.bku.slexceptions.SLCommandException;
 import at.gv.egiz.bku.slexceptions.SLRequestException;
 import at.gv.egiz.bku.slexceptions.SLRuntimeException;
@@ -81,10 +89,6 @@ import at.gv.egiz.bku.viewer.Validator;
 import at.gv.egiz.bku.viewer.ValidatorFactory;
 import at.gv.egiz.dom.DOMUtils;
 import at.gv.egiz.slbinding.impl.XMLContentType;
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URL;
 
 /**
  * This class represents a <code>DataObject</code> of an XML-Signature
@@ -97,7 +101,7 @@ public class DataObject {
   /**
    * Logging facility.
    */
-  private static Log log = LogFactory.getLog(DataObject.class);
+  private final Logger log = LoggerFactory.getLogger(DataObject.class);
   
   /**
    * DOM Implementation.
@@ -205,7 +209,7 @@ public class DataObject {
 
     domImplLS = (DOMImplementationLS) registry.getDOMImplementation(DOM_LS_3_0);
     if (domImplLS == null) {
-      log.error("Failed to get DOMImplementation " + DOM_LS_3_0);
+      log.error("Failed to get DOMImplementation {}.", DOM_LS_3_0);
       throw new SLRuntimeException("Failed to get DOMImplementation " + DOM_LS_3_0);
     }
 
@@ -276,7 +280,7 @@ public class DataObject {
         try {
           validator = ValidatorFactory.newValidator(mediaType);
         } catch (IllegalArgumentException e) {
-          log.error("No validator found for mime type '" + mediaType + "'.");
+          log.error("No validator found for mime type '{}'.", mediaType, e);
           throw new SLViewerException(5000);
         }
         
@@ -299,7 +303,7 @@ public class DataObject {
         }
         
       } else {
-        log.debug("MIME media type '" + mediaType + "' is not a s/valid/SUPPORTED digest input, omitting validation.");
+        log.debug("MIME media type '{}' is not a s/valid/SUPPORTED digest input, omitting validation.", mediaType);
       }
     }
     
@@ -359,12 +363,12 @@ public class DataObject {
     if (reference != null) {
       if (reference.getURI() != null && !"".equals(reference.getURI())) {
         try {
-          log.info("deriving filename from reference URI " + reference.getURI());
+          log.info("Deriving filename from reference URI {}.", reference.getURI());
           URI refURI = new URI(reference.getURI());
 
           if (refURI.isOpaque()) {
             // could check scheme component, but also allow other schemes (e.g. testlocal)
-            log.trace("opaque reference URI, use scheme-specific part as filename");
+            log.trace("Opaque reference URI, use scheme-specific part as filename.");
             filename = refURI.getSchemeSpecificPart();
             if (!hasExtension(filename)) {
               filename += MimeTypes.getExtension(mimeType);
@@ -376,34 +380,34 @@ public class DataObject {
           } else if ("".equals(refURI.getPath()) && 
                   refURI.getFragment() != null &&
                   refURI.getFragment().indexOf('(') < 0) { // exclude (schemebased) xpointer expressions
-            log.trace("fragment (shorthand xpointer) URI, use fragment as filename");
+            log.trace("Fragment (shorthand xpointer) URI, use fragment as filename.");
             filename = refURI.getFragment();
             if(!hasExtension(filename)) {
               filename += MimeTypes.getExtension(mimeType);
             }
           } else if (!"".equals(refURI.getPath())) {
-            log.trace("hierarchical URI with path component, use path as filename");
+            log.trace("Hierarchical URI with path component, use path as filename.");
             File refFile = new File(refURI.getPath());
             filename = refFile.getName();
             if(!hasExtension(filename)) {
               filename += MimeTypes.getExtension(mimeType);
             }
           } else {
-            log.debug("failed to derive filename from URI '" + refURI + "', derive filename from reference ID");
+            log.debug("Failed to derive filename from URI '{}', derive filename from reference ID.", refURI);
             filename = reference.getId() + MimeTypes.getExtension(mimeType);
           }
         } catch (URISyntaxException ex) {
-          log.error("failed to derive filename from invalid URI " + ex.getMessage());
+          log.error("Failed to derive filename from invalid URI {}.", ex.getMessage());
           filename = reference.getId() + MimeTypes.getExtension(mimeType);
         }
       } else {
-        log.debug("same-document URI, derive filename from reference ID");
+        log.debug("Same-document URI, derive filename from reference ID.");
         filename = reference.getId() + MimeTypes.getExtension(mimeType);
       }
     } else {
-      log.error("failed to derive filename, no reference created");
+      log.error("Failed to derive filename, no reference created.");
     }
-    log.debug("derived filename for reference " + reference.getId() + ": " + filename);
+    log.debug("Derived filename for reference {}: {}.", reference.getId(), filename);
     return filename;
   }
 
@@ -413,30 +417,12 @@ public class DataObject {
   }
 
   private byte[] getTransformsBytes(at.gv.egiz.slbinding.impl.TransformsInfoType ti) {
-    return ti.getRedirectedStream().toByteArray();
-//    byte[] transformsBytes = ti.getRedirectedStream().toByteArray();
-//
-//    if (transformsBytes == null || transformsBytes.length == 0) {
-//      return null;
-//    }
-//
-//    String dsigPrefix = ti.getNamespaceContext().getNamespaceURI("http://www.w3.org/2000/09/xmldsig#");
-//    byte[] pre, post;
-//    if (dsigPrefix == null) {
-//      log.trace("XMLDSig not declared in outside dsig:Transforms");
-//      pre = "<AssureDSigNS>".getBytes();
-//      post = "</AssureDSigNS>".getBytes();
-//    } else {
-//      log.trace("XMLDSig bound to prefix " + dsigPrefix);
-//       pre = ("<AssureDSigNS xmlns:" + dsigPrefix + "=\"http://www.w3.org/2000/09/xmldsig#\">").getBytes();
-//       post = "</AssureDSigNS>".getBytes();
-//    }
-//
-//    byte[] workaround = new byte[pre.length + transformsBytes.length + post.length];
-//    System.arraycopy(pre, 0, workaround, 0, pre.length);
-//    System.arraycopy(transformsBytes, 0, workaround, pre.length, transformsBytes.length);
-//    System.arraycopy(post, 0, workaround, pre.length + transformsBytes.length, post.length);
-//    return workaround;
+    ByteArrayOutputStream redirectedStream = ti.getRedirectedStream();
+    if (redirectedStream != null) {
+      return redirectedStream.toByteArray();
+    } else {
+      return null;
+    }
   }
 
   /**
@@ -487,9 +473,8 @@ public class DataObject {
 
         // create XMLObject
         DocumentFragment content = parseDataObject((XMLContentType) dataObject.getXMLContent());
-        XMLObject xmlObject = createXMLObject(content);
         
-        setXMLObjectAndReferenceXML(xmlObject, transforms);
+        setXMLObjectAndReferenceXML(createXMLObject(content), transforms);
         
       } else if (dataObject.getLocRefContent() != null) {
         
@@ -521,7 +506,7 @@ public class DataObject {
         // The content of sl:DataObject remains empty
         //
         
-        log.debug("Adding DataObject from reference URI '" + reference + "'.");
+        log.debug("Adding DataObject from reference URI '{}'.", reference);
         
         setEnvelopedDataObject(reference, transforms);
         
@@ -564,13 +549,13 @@ public class DataObject {
     }
     
     // dereference URL
-    URLDereferencer dereferencer = URLDereferencer.getInstance();
+    URLDereferencer dereferencer = ctx.getUrlDereferencer();
     
     StreamData streamData;
     try {
-      streamData = dereferencer.dereference(reference, ctx.getDereferencerContext());
+      streamData = dereferencer.dereference(reference);
     } catch (IOException e) {
-      log.info("Failed to dereference XMLObject from '" + reference + "'.", e);
+      log.info("Failed to dereference XMLObject from '{}'.", reference, e);
       throw new SLCommandException(4110);
     }
 
@@ -587,7 +572,7 @@ public class DataObject {
       childNode = doc.getDocumentElement();
       
       if (childNode == null) {
-        log.info("Failed to parse XMLObject from '" + reference + "'.");
+        log.info("Failed to parse XMLObject from '{}'.", reference);
         throw new SLCommandException(4111);
       }
       
@@ -666,12 +651,12 @@ public class DataObject {
       if (dataObject.getLocRefContent() != null) {
         String locRef = dataObject.getLocRefContent();
         try {
-          this.reference.setDereferencer(new LocRefDereferencer(ctx.getDereferencerContext(), locRef));
+          this.reference.setDereferencer(new LocRefDereferencer(ctx.getUrlDereferencer(), locRef));
         } catch (URISyntaxException e) {
-          log.info("Invalid URI '" + locRef + "' in DataObject.", e);
+          log.info("Invalid URI '{}' in DataObject.", locRef, e);
           throw new SLCommandException(4003);
         } catch (IllegalArgumentException e) {
-          log.info("LocRef URI of '" + locRef + "' not supported in DataObject. ", e);
+          log.info("LocRef URI of '{}' not supported in DataObject. ", locRef, e);
           throw new SLCommandException(4003);
         }
       } else if (dataObject.getBase64Content() != null) {
@@ -734,7 +719,7 @@ public class DataObject {
     }
 
     if (debugString != null) {
-      log.debug(debugString);
+      log.debug(debugString.toString());
     }
 
     // look for preferred transform
@@ -778,7 +763,7 @@ public class DataObject {
         StringBuilder sb = new StringBuilder();
         sb.append("Trying to parse transforms:\n");
         sb.append(new String(transforms, Charset.forName("UTF-8")));
-        log.trace(sb);
+        log.trace(sb.toString());
       }
 
       DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS();
@@ -933,8 +918,7 @@ public class DataObject {
       } catch (MarshalException e) {
       
         String mimeType = preferredTransformsInfo.getFinalDataMetaInfo().getMimeType();
-        log.info("Failed to unmarshal preferred transformation path (MIME-Type="
-            + mimeType + ").", e);
+        log.info("Failed to unmarshal preferred transformation path (MIME-Type={}).", mimeType, e);
       
       }
 
@@ -950,8 +934,7 @@ public class DataObject {
       } catch (MarshalException e) {
 
         String mimeType = transformsInfoType.getFinalDataMetaInfo().getMimeType();
-        log.info("Failed to unmarshal transformation path (MIME-Type="
-            + mimeType + ").", e);
+        log.info("Failed to unmarshal transformation path (MIME-Type={}).", mimeType, e);
       }
       
     }
@@ -975,7 +958,7 @@ public class DataObject {
     try {
       textNode = at.gv.egiz.dom.DOMUtils.createBase64Text(content, ctx.getDocument());
     } catch (IOException e) {
-      log.error(e);
+      log.error("Failed to create XMLObject.", e);
       throw new SLRuntimeException(e);
     }
 
@@ -1170,36 +1153,68 @@ public class DataObject {
     // content of the redirect stream as the content has already been parsed
     // and serialized again to the redirect stream.
     
-    List<InputStream> inputStreams = new ArrayList<InputStream>();
-    try {
-      // dummy start element
-      inputStreams.add(new ByteArrayInputStream("<dummy>".getBytes("UTF-8")));
-  
-      // content
-      inputStreams.add(new ByteArrayInputStream(redirectedStream.toByteArray()));
-      
-      // dummy end element
-      inputStreams.add(new ByteArrayInputStream("</dummy>".getBytes("UTF-8")));
-    } catch (UnsupportedEncodingException e) {
-      throw new SLRuntimeException(e);
-    }
+    DocumentFragment fragment;
+    if (redirectedStream != null) {
     
-    SequenceInputStream inputStream = new SequenceInputStream(Collections.enumeration(inputStreams));
-  
-    // parse DataObject
-    Document doc = parseDataObject(inputStream, "UTF-8");
+      List<InputStream> inputStreams = new ArrayList<InputStream>();
+      try {
+        // dummy start element
+        inputStreams.add(new ByteArrayInputStream("<dummy>".getBytes("UTF-8")));
     
-    Element documentElement = doc.getDocumentElement();
-  
-    if (documentElement == null ||
-        !"dummy".equals(documentElement.getLocalName())) {
-      log.info("Failed to parse DataObject XMLContent.");
-      throw new SLCommandException(4111);
-    }
+        // content
+        inputStreams.add(new ByteArrayInputStream(redirectedStream.toByteArray()));
+        
+        // dummy end element
+        inputStreams.add(new ByteArrayInputStream("</dummy>".getBytes("UTF-8")));
+      } catch (UnsupportedEncodingException e) {
+        throw new SLRuntimeException(e);
+      }
+      
+      SequenceInputStream inputStream = new SequenceInputStream(Collections.enumeration(inputStreams));
     
-    DocumentFragment fragment = doc.createDocumentFragment();
-    while (documentElement.getFirstChild() != null) {
-      fragment.appendChild(documentElement.getFirstChild());
+      // parse DataObject
+      Document doc = parseDataObject(inputStream, "UTF-8");
+      
+      Element documentElement = doc.getDocumentElement();
+    
+      if (documentElement == null ||
+          !"dummy".equals(documentElement.getLocalName())) {
+        log.info("Failed to parse DataObject XMLContent.");
+        throw new SLCommandException(4111);
+      }
+      
+      fragment = doc.createDocumentFragment();
+      while (documentElement.getFirstChild() != null) {
+        fragment.appendChild(documentElement.getFirstChild());
+      }
+
+    } else {
+      
+      fragment = ctx.getDocument().createDocumentFragment();
+      Marshaller marshaller = SLMarshallerFactory.getInstance().createMarshaller(false);
+      
+      JAXBElement<at.buergerkarte.namespaces.securitylayer._1.XMLContentType> element = 
+        new JAXBElement<at.buergerkarte.namespaces.securitylayer._1.XMLContentType>(
+          new QName("dummy"),
+          at.buergerkarte.namespaces.securitylayer._1.XMLContentType.class,
+          xmlContent);
+      
+      try {
+        marshaller.marshal(element, fragment);
+      } catch (JAXBException e) {
+        log.info("Failed to marshal DataObject (XMLContent).", e);
+        throw new SLCommandException(4111);
+      }
+      
+      Node dummy = fragment.getFirstChild();
+      if (dummy != null) {
+        NodeList nodes = dummy.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+          fragment.appendChild(nodes.item(i));
+        }
+        fragment.removeChild(dummy);
+      }
+
     }
     
     // log parsed document
@@ -1256,6 +1271,8 @@ public class DataObject {
     SimpleDOMErrorHandler errorHandler = new SimpleDOMErrorHandler();
     domConfig.setParameter("error-handler", errorHandler);
     domConfig.setParameter("validate", Boolean.FALSE);
+    domConfig.setParameter("entities", Boolean.TRUE);
+    
 
     Document doc;
     try {
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/LocRefDereferencer.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/LocRefDereferencer.java
index f5394157..e513738c 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/LocRefDereferencer.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/LocRefDereferencer.java
@@ -14,99 +14,96 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-package at.gv.egiz.bku.slcommands.impl.xsect;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-import javax.xml.crypto.Data;
-import javax.xml.crypto.OctetStreamData;
-import javax.xml.crypto.URIDereferencer;
-import javax.xml.crypto.URIReference;
-import javax.xml.crypto.URIReferenceException;
-import javax.xml.crypto.XMLCryptoContext;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.bku.utils.urldereferencer.StreamData;
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
-
-/**
- * An URIDereferencer implementation that dereferences <code>LocRef</code>
- * references.
- * 
- * @author mcentner
- */
-public class LocRefDereferencer implements URIDereferencer {
-
-  /**
-   * Logging facility.
-   */
-  private static Log log = LogFactory.getLog(LocRefDereferencer.class);
-
-  /**
-   * The <code>LocRef</code>-reference to be dereferenced by
-   * {@link #dereference(URIReference, XMLCryptoContext)}.
-   */
-  protected String locRef;
-
-  /**
-   * The context to be used for dereferencing.
-   */
-  protected URLDereferencerContext dereferencerContext;
-
-  /**
-   * Creates a new instance of this LocRefDereferencer with the given
-   * <code>dereferencerContext</code> and <code>locRef</code> reference.
-   * 
-   * @param dereferencerContext
-   *          the context to be used for dereferencing
-   * @param locRef
-   *          the <code>LocRef</code>-reference (must be an absolute URI)
-   * 
-   * @throws URISyntaxException
-   *           if <code>LocRef</code> is not an absolute URI
-   */
-  public LocRefDereferencer(URLDereferencerContext dereferencerContext,
-      String locRef) throws URISyntaxException {
-
-    this.dereferencerContext = dereferencerContext;
-
-    URI locRefUri = new URI(locRef);
-    if (locRefUri.isAbsolute()) {
-      this.locRef = locRef;
-    } else {
-      throw new IllegalArgumentException(
-          "Parameter 'locRef' must be an absolut URI.");
-    }
-  }
-
-  /*
-   * (non-Javadoc)
-   * 
-   * @see
-   * javax.xml.crypto.URIDereferencer#dereference(javax.xml.crypto.URIReference,
-   * javax.xml.crypto.XMLCryptoContext)
-   */
-  @Override
-  public Data dereference(URIReference uriReference, XMLCryptoContext context)
-      throws URIReferenceException {
-
-    URLDereferencer dereferencer = URLDereferencer.getInstance();
-    StreamData streamData;
-    try {
-      streamData = dereferencer.dereference(locRef, dereferencerContext);
-    } catch (IOException e) {
-      log.info("Failed to dereference URI'" + locRef + "'. " + e.getMessage(),
-          e);
-      throw new URIReferenceException("Failed to dereference URI '" + locRef
-          + "'. " + e.getMessage(), e);
-    }
-    return new OctetStreamData(streamData.getStream(), locRef, streamData
-        .getContentType());
-  }
-
-}
+package at.gv.egiz.bku.slcommands.impl.xsect;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.xml.crypto.Data;
+import javax.xml.crypto.OctetStreamData;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.URIReference;
+import javax.xml.crypto.URIReferenceException;
+import javax.xml.crypto.XMLCryptoContext;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.bku.utils.urldereferencer.StreamData;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
+
+/**
+ * An URIDereferencer implementation that dereferences <code>LocRef</code>
+ * references.
+ * 
+ * @author mcentner
+ */
+public class LocRefDereferencer implements URIDereferencer {
+
+  /**
+   * Logging facility.
+   */
+  private final Logger log = LoggerFactory.getLogger(LocRefDereferencer.class);
+
+  /**
+   * The <code>LocRef</code>-reference to be dereferenced by
+   * {@link #dereference(URIReference, XMLCryptoContext)}.
+   */
+  protected String locRef;
+
+  /**
+   * The URLDereferencer to be used for dereferencing.
+   */
+  protected URLDereferencer dereferencer;
+
+  /**
+   * Creates a new instance of this LocRefDereferencer with the given
+   * <code>dereferencerContext</code> and <code>locRef</code> reference.
+   * 
+   * @param dereferencer
+   *          the context to be used for dereferencing
+   * @param locRef
+   *          the <code>LocRef</code>-reference (must be an absolute URI)
+   * 
+   * @throws URISyntaxException
+   *           if <code>LocRef</code> is not an absolute URI
+   */
+  public LocRefDereferencer(URLDereferencer dereferencer,
+      String locRef) throws URISyntaxException {
+
+    this.dereferencer = dereferencer;
+
+    URI locRefUri = new URI(locRef);
+    if (locRefUri.isAbsolute()) {
+      this.locRef = locRef;
+    } else {
+      throw new IllegalArgumentException(
+          "Parameter 'locRef' must be an absolut URI.");
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * javax.xml.crypto.URIDereferencer#dereference(javax.xml.crypto.URIReference,
+   * javax.xml.crypto.XMLCryptoContext)
+   */
+  @Override
+  public Data dereference(URIReference uriReference, XMLCryptoContext context)
+      throws URIReferenceException {
+
+    StreamData streamData;
+    try {
+      streamData = dereferencer.dereference(locRef);
+    } catch (IOException e) {
+      log.info("Failed to dereference URI '{}'.", locRef, e);
+      throw new URIReferenceException("Failed to dereference URI '" + locRef
+          + "'. " + e.getMessage(), e);
+    }
+    return new OctetStreamData(streamData.getStream(), locRef, streamData
+        .getContentType());
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALPrivateKey.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALPrivateKey.java
index 25e2d4e5..87a165cf 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALPrivateKey.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALPrivateKey.java
@@ -16,7 +16,6 @@
 */
 package at.gv.egiz.bku.slcommands.impl.xsect;
 
-import at.gv.egiz.stal.HashDataInput;
 import java.security.PrivateKey;
 
 import at.gv.egiz.stal.STAL;
@@ -24,7 +23,7 @@ import at.gv.egiz.stal.STAL;
 import java.util.List;
 
 /**
- * This class implements a private key used by the {@link STALSignature} class. 
+ * This class implements a private key used by the {@link STALSignatureMethod} class. 
  * 
  * @author mcentner
  */
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java
deleted file mode 100644
index 9fb9a3f1..00000000
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package at.gv.egiz.bku.slcommands.impl.xsect;
-
-import iaik.xml.crypto.XmldsigMore;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.Provider;
-import java.security.Signature;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.xml.crypto.dsig.SignatureMethod;
-
-/**
- * A security provider implementation that provides {@link Signature} implementations
- * based on STAL.
- * 
- * @author mcentner
- */
-public class STALProvider extends Provider {
-
-  private static final long serialVersionUID = 1L;
-  
-  private static String IMPL_PACKAGE_NAME = "at.gv.egiz.bku.slcommands.impl.xsect";
-  
-  public STALProvider() {
-    
-    super("STAL", 1.0, "Security Token Abstraction Layer Provider");
-  
-    final Map<String, String> map = new HashMap<String, String>();
-
-    // TODO: register further algorithms
-    map.put("Signature." + SignatureMethod.RSA_SHA1,
-        IMPL_PACKAGE_NAME + ".STALSignature");
-    map.put("Signature." + XmldsigMore.SIGNATURE_ECDSA_SHA1, 
-        IMPL_PACKAGE_NAME + ".STALSignature");
-    map.put("Signature." + XmldsigMore.SIGNATURE_RSA_SHA256, 
-        IMPL_PACKAGE_NAME + ".STALSignature");
-    map.put("Signature." + XmldsigMore.SIGNATURE_ECDSA_SHA256, 
-        IMPL_PACKAGE_NAME + ".STALSignature");
-    map.put("Signature." + XmldsigMore.SIGNATURE_ECDSA_SHA512, 
-        IMPL_PACKAGE_NAME + ".STALSignature");
-
-
-    AccessController.doPrivileged(new PrivilegedAction<Void>() {
-      @Override
-      public Void run() {
-        putAll(map);
-        return null;
-      }
-    });
-  
-  }
-  
-}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignature.java
deleted file mode 100644
index dd7c7d8a..00000000
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignature.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package at.gv.egiz.bku.slcommands.impl.xsect;
-
-import at.gv.egiz.bku.slcommands.impl.DataObjectHashDataInput;
-import at.gv.egiz.bku.slexceptions.SLViewerException;
-
-import java.io.ByteArrayOutputStream;
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SignatureException;
-import java.security.SignatureSpi;
-import java.util.Collections;
-import java.util.List;
-
-import at.gv.egiz.stal.ErrorResponse;
-import at.gv.egiz.stal.HashDataInput;
-import at.gv.egiz.stal.STAL;
-import at.gv.egiz.stal.STALRequest;
-import at.gv.egiz.stal.STALResponse;
-import at.gv.egiz.stal.SignRequest;
-import at.gv.egiz.stal.SignResponse;
-//import at.gv.egiz.stal.HashDataInputCallback;
-import java.util.ArrayList;
-
-/**
- * A signature service provider implementation that uses STAL to sign.
- * 
- * @author mcentner
- */
-public class STALSignature extends SignatureSpi {
-
-//    private static final Log log = LogFactory.getLog(STALSignature.class);
-    
-  /**
-   * The private key.
-   */
-  protected STALPrivateKey privateKey;
-  
-  /**
-   * The to-be signed data.
-   */
-  protected ByteArrayOutputStream data = new ByteArrayOutputStream();
-  
-  /* (non-Javadoc)
-   * @see java.security.SignatureSpi#engineGetParameter(java.lang.String)
-   */
-  @Override
-  protected Object engineGetParameter(String param)
-      throws InvalidParameterException {
-    throw new InvalidParameterException();
-  }
-
-  /* (non-Javadoc)
-   * @see java.security.SignatureSpi#engineInitSign(java.security.PrivateKey)
-   */
-  @Override
-  protected void engineInitSign(PrivateKey privateKey)
-      throws InvalidKeyException {
-
-    if (!(privateKey instanceof STALPrivateKey)) {
-      throw new InvalidKeyException("STALSignature supports STALKeys only.");
-    }
-    
-    this.privateKey = (STALPrivateKey) privateKey;
-
-  }
-
-  /* (non-Javadoc)
-   * @see java.security.SignatureSpi#engineInitVerify(java.security.PublicKey)
-   */
-  @Override
-  protected void engineInitVerify(PublicKey publicKey)
-      throws InvalidKeyException {
-    
-    throw new UnsupportedOperationException("STALSignature does not support signature verification.");
-  }
-
-  /* (non-Javadoc)
-   * @see java.security.SignatureSpi#engineSetParameter(java.lang.String, java.lang.Object)
-   */
-  @Override
-  protected void engineSetParameter(String param, Object value)
-      throws InvalidParameterException {
-  }
-
-  /* (non-Javadoc)
-   * @see java.security.SignatureSpi#engineSign()
-   */
-  @Override
-  protected byte[] engineSign() throws SignatureException {
-   
-    STAL stal = privateKey.getStal();
-    
-    if (stal == null) {
-      throw new SignatureException("STALSignature requires the STALPrivateKey " +
-      		"to provide a STAL implementation reference.");
-    }
-    
-    String keyboxIdentifier = privateKey.getKeyboxIdentifier();
-    
-    if (keyboxIdentifier == null) {
-      throw new SignatureException("STALSignature requires the STALPrivateKey " + 
-          "to provide a KeyboxIdentifier.");
-    }
-    
-    // get hashDataInputs (DigestInputStreams) once slcommands.impl.xsect.Signature::sign() was called
-    List<DataObject> dataObjects = privateKey.getDataObjects();
-//    log.debug("got " + dataObjects.size() + " DataObjects, passing HashDataInputs to STAL SignRequest");
-    
-    List<HashDataInput> hashDataInputs = new ArrayList<HashDataInput>();
-    for (DataObject dataObject : dataObjects) {
-      try {
-        dataObject.validateHashDataInput();
-      } catch (SLViewerException e) {
-        throw new STALSignatureException(e);
-      }
-      hashDataInputs.add(new DataObjectHashDataInput(dataObject));
-    }
-    
-    SignRequest signRequest = new SignRequest();
-    signRequest.setKeyIdentifier(keyboxIdentifier);
-    signRequest.setSignedInfo(data.toByteArray());
-    signRequest.setHashDataInput(hashDataInputs);
-    
-    List<STALResponse> responses = stal.handleRequest(Collections.singletonList((STALRequest) signRequest));
-    
-    if (responses == null || responses.size() != 1) {
-      throw new SignatureException("Failed to access STAL.");
-    }
-
-    STALResponse response = responses.get(0);
-    if (response instanceof SignResponse) {
-      return ((SignResponse) response).getSignatureValue();
-    } else if (response instanceof ErrorResponse) {
-      throw new STALSignatureException(((ErrorResponse) response).getErrorCode());
-    } else {
-      throw new SignatureException("Failed to access STAL.");
-    }
-
-  }
-
-  /* (non-Javadoc)
-   * @see java.security.SignatureSpi#engineUpdate(byte)
-   */
-  @Override
-  protected void engineUpdate(byte b) throws SignatureException {
-    data.write(b);
-  }
-
-  /* (non-Javadoc)
-   * @see java.security.SignatureSpi#engineUpdate(byte[], int, int)
-   */
-  @Override
-  protected void engineUpdate(byte[] b, int off, int len)
-      throws SignatureException {
-    data.write(b, off, len);
-  }
-
-  /* (non-Javadoc)
-   * @see java.security.SignatureSpi#engineVerify(byte[])
-   */
-  @Override
-  protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
-    throw new UnsupportedOperationException("STALSignature des not support signature verification.");
-  }
-
-}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureException.java
index 4e86b07c..b727600f 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureException.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureException.java
@@ -19,7 +19,7 @@ package at.gv.egiz.bku.slcommands.impl.xsect;
 import java.security.SignatureException;
 
 /**
- * A SignatureException thrown by the {@link STALSignature}.
+ * A SignatureException thrown by the {@link STALSignatureMethod}.
  * 
  * @author mcentner
  */
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureMethod.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureMethod.java
new file mode 100644
index 00000000..a9bb8e04
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureMethod.java
@@ -0,0 +1,127 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.slcommands.impl.xsect;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
+
+import at.gv.egiz.bku.slcommands.impl.DataObjectHashDataInput;
+import at.gv.egiz.bku.slexceptions.SLViewerException;
+import at.gv.egiz.bku.utils.StreamUtil;
+import at.gv.egiz.stal.ErrorResponse;
+import at.gv.egiz.stal.HashDataInput;
+import at.gv.egiz.stal.STAL;
+import at.gv.egiz.stal.STALRequest;
+import at.gv.egiz.stal.STALResponse;
+import at.gv.egiz.stal.SignRequest;
+import at.gv.egiz.stal.SignResponse;
+
+import iaik.xml.crypto.dsig.AbstractSignatureMethodImpl;
+
+public class STALSignatureMethod extends AbstractSignatureMethodImpl {
+  
+  /**
+   * Creates a new instance of this <code>STALSignatureMethod</code>
+   * with the given <code>algorithm</code> and <code>params</code>.
+   * 
+   * @param algorithm the algorithm URI
+   * @param params optional algorithm parameters
+   * @throws InvalidAlgorithmParameterException if the specified parameters 
+   * are inappropriate for the requested algorithm
+   * @throws NoSuchAlgorithmException if an implementation of the specified 
+   * algorithm cannot be found
+   * @throws NullPointerException if <code>algorithm</code> is <code>null</code>  
+   */
+  public STALSignatureMethod(String algorithm,
+      SignatureMethodParameterSpec params)
+      throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
+    super(algorithm, params);
+  }
+
+  @Override
+  public byte[] calculateSignatureValue(XMLCryptoContext context, Key key, InputStream message)
+      throws XMLSignatureException, IOException {
+    
+    if (!(key instanceof STALPrivateKey)) {
+      throw new XMLSignatureException("STALSignatureMethod expects STALPrivateKey.");
+    }
+
+    STAL stal = ((STALPrivateKey) key).getStal();
+    String keyboxIdentifier = ((STALPrivateKey) key).getKeyboxIdentifier();
+    List<DataObject> dataObjects = ((STALPrivateKey) key).getDataObjects();
+    
+    List<HashDataInput> hashDataInputs = new ArrayList<HashDataInput>();
+    for (DataObject dataObject : dataObjects) {
+      try {
+        dataObject.validateHashDataInput();
+      } catch (SLViewerException e) {
+        throw new XMLSignatureException(e);
+      }
+      hashDataInputs.add(new DataObjectHashDataInput(dataObject));
+    }
+    
+    ByteArrayOutputStream m = new ByteArrayOutputStream();
+    StreamUtil.copyStream(message, m);
+    
+    SignRequest signRequest = new SignRequest();
+    signRequest.setKeyIdentifier(keyboxIdentifier);
+    signRequest.setSignedInfo(m.toByteArray());
+    signRequest.setHashDataInput(hashDataInputs);
+
+    List<STALResponse> responses = 
+      stal.handleRequest(Collections.singletonList((STALRequest) signRequest));
+    
+    if (responses == null || responses.size() != 1) {
+      throw new XMLSignatureException("Failed to access STAL.");
+    }
+
+    STALResponse response = responses.get(0);
+    if (response instanceof SignResponse) {
+      return ((SignResponse) response).getSignatureValue();
+    } else if (response instanceof ErrorResponse) {
+      STALSignatureException se = new STALSignatureException(((ErrorResponse) response).getErrorCode());
+      throw new XMLSignatureException(se);
+    } else {
+      throw new XMLSignatureException("Failed to access STAL.");
+    }
+    
+  }
+
+  @Override
+  public boolean validateSignatureValue(XMLCryptoContext context, Key key, byte[] value,
+      InputStream message) throws XMLSignatureException, IOException {
+    throw new XMLSignatureException("The STALSignatureMethod does not support validation.");
+  }
+
+  @Override
+  protected Class<?> getParameterSpecClass() {
+    return null;
+  }
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
index 3cebb6a3..b4ce0e79 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
@@ -51,8 +51,8 @@ import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
 import javax.xml.crypto.dsig.keyinfo.X509Data;
 import javax.xml.stream.XMLStreamException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.etsi.uri._01903.v1_1.DataObjectFormatType;
 import org.etsi.uri._01903.v1_1.QualifyingPropertiesType;
 import org.w3c.dom.DOMConfiguration;
@@ -82,7 +82,6 @@ import at.gv.egiz.bku.slexceptions.SLViewerException;
 import at.gv.egiz.bku.utils.HexDump;
 import at.gv.egiz.bku.utils.urldereferencer.StreamData;
 import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
 import at.gv.egiz.dom.DOMUtils;
 import at.gv.egiz.slbinding.impl.XMLContentType;
 import at.gv.egiz.stal.STAL;
@@ -101,7 +100,7 @@ public class Signature {
   /**
    * Logging facility.
    */
-  private static Log log = LogFactory.getLog(Signature.class);
+  private final Logger log = LoggerFactory.getLogger(Signature.class);
 
   /**
    * The DOM implementation used.
@@ -151,8 +150,9 @@ public class Signature {
   
   /**
    * Creates a new SLXMLSignature instance.
+   * @param urlDereferencer TODO
    */
-  public Signature(URLDereferencerContext dereferencerContext,
+  public Signature(URLDereferencer urlDereferencer,
       IdValueFactory idValueFactory,
       AlgorithmMethodFactory algorithmMethodFactory) {
     
@@ -162,7 +162,7 @@ public class Signature {
   
     ctx.setSignatureFactory(XMLSignatureFactory.getInstance());
 
-    ctx.setDereferencerContext(dereferencerContext);
+    ctx.setUrlDereferencer(urlDereferencer);
     ctx.setIdValueFactory(idValueFactory);
     ctx.setAlgorithmMethodFactory(algorithmMethodFactory);
     
@@ -408,7 +408,7 @@ public class Signature {
     
     signContext.putNamespacePrefix(XMLSignature.XMLNS,XMLDSIG_PREFIX); 
     
-    signContext.setURIDereferencer(new URIDereferncerAdapter(ctx.getDereferencerContext()));
+    signContext.setURIDereferencer(new URIDereferncerAdapter(ctx.getUrlDereferencer()));
     
     try {
       xmlSignature.sign(signContext);
@@ -455,7 +455,7 @@ public class Signature {
               sb.append(HexDump.hexDump(digestInputStream));
             }
           } catch (IOException e) {
-            log.error(e);
+            log.error("Failed to log DigestInput.", e);
           }
           log.trace(sb.toString());
         } else {
@@ -478,7 +478,7 @@ public class Signature {
                 sb.append(new String(b, 0, l));
               }
             } catch (IOException e) {
-              log.error(e);
+              log.error("Failed to log DigestInput.", e);
             }
             log.trace(sb.toString());
           } else {
@@ -735,7 +735,7 @@ public class Signature {
     LSInput input;
     try {
       if (signatureEnvironment.getReference() != null) {
-        log.debug("SignatureEnvironment contains Reference " + signatureEnvironment.getReference() + ".");
+        log.debug("SignatureEnvironment contains Reference '{}'.", signatureEnvironment.getReference());
         input = createLSInput(signatureEnvironment.getReference());
       } else if (signatureEnvironment.getBase64Content() != null) {
         log.debug("SignatureEnvironment contains Base64Content.");
@@ -784,11 +784,12 @@ public class Signature {
       if (log.isInfoEnabled()) {
         List<String> errorMessages = errorHandler.getErrorMessages();
         StringBuffer sb = new StringBuffer();
+        sb.append("XML document in which the signature is to be integrated cannot be parsed.");
         for (String errorMessage : errorMessages) {
           sb.append(" ");
           sb.append(errorMessage);
         }
-        log.info("XML document in which the signature is to be integrated cannot be parsed." + sb.toString());
+        log.info(sb.toString());
       }
       throw new SLCommandException(4101);
     }
@@ -826,8 +827,8 @@ public class Signature {
    */
   private LSInput createLSInput(String reference) throws IOException {
     
-    URLDereferencer urlDereferencer = URLDereferencer.getInstance();
-    StreamData streamData = urlDereferencer.dereference(reference, ctx.getDereferencerContext());
+    URLDereferencer urlDereferencer = ctx.getUrlDereferencer();
+    StreamData streamData = urlDereferencer.dereference(reference);
 
     String contentType = streamData.getContentType();
     String charset = HttpUtil.getCharset(contentType, true);
@@ -835,7 +836,7 @@ public class Signature {
     try {
       streamReader = new InputStreamReader(streamData.getStream(), charset);
     } catch (UnsupportedEncodingException e) {
-      log.info("Charset " + charset + " not supported. Using default.");
+      log.info("Charset {} not supported. Using default.", charset);
       streamReader = new InputStreamReader(streamData.getStream());
     }
 
@@ -942,7 +943,7 @@ public class Signature {
   
       if (systemId != null) {
 
-        log.debug("Resolve resource '" + systemId + "'.");
+        log.debug("Resolve resource '{}'.", systemId);
         
         for (DataObjectAssociationType supplement : supplements) {
           
@@ -954,23 +955,23 @@ public class Signature {
               
               try {
                 if (content.getLocRefContent() != null) {
-                  log.trace("Resolved resource '" + reference + "' to supplement with LocRefContent.");
+                  log.trace("Resolved resource '{}' to supplement with LocRefContent.", reference);
                   return createLSInput(content.getLocRefContent());
                 } else if (content.getBase64Content() != null) {
-                  log.trace("Resolved resource '" + reference + "' to supplement with Base64Content.");
+                  log.trace("Resolved resource '{}' to supplement with Base64Content.", reference);
                   return createLSInput(content.getBase64Content());
                 } else if (content.getXMLContent() != null) {
-                  log.trace("Resolved resource '" + reference + "' to supplement with XMLContent.");
+                  log.trace("Resolved resource '{}' to supplement with XMLContent.", reference);
                   return createLSInput((XMLContentType) content.getXMLContent());
                 } else {
                   return null;
                 }
               } catch (IOException e) {
-                log.info("Failed to resolve resource '" + systemId + "' to supplement.", e);
+                log.info("Failed to resolve resource '{}' to supplement.", systemId, e);
                 error = e;
                 return null;
               } catch (XMLStreamException e) {
-                log.info("Failed to resolve resource '" + systemId + "' to supplement.", e);
+                log.info("Failed to resolve resource '{}' to supplement.", systemId, e);
                 error = e;
                 return null;
               }
@@ -981,7 +982,7 @@ public class Signature {
           
         }
 
-        log.info("Failed to resolve resource '" + systemId + "' to supplement. No such supplement.");
+        log.info("Failed to resolve resource '{}' to supplement. No such supplement.", systemId);
         
       }
   
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureContext.java
index 0925f2fd..48c82bd5 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureContext.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureContext.java
@@ -16,12 +16,12 @@
 */
 package at.gv.egiz.bku.slcommands.impl.xsect;
 
-import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.AlgorithmMethod;
 import javax.xml.crypto.dsig.XMLSignatureFactory;
 
 import org.w3c.dom.Document;
 
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
 
 /**
  * An instance of this class carries context information for a XML-Signature
@@ -45,16 +45,16 @@ public class SignatureContext {
    * The XMLSignatureFactory to create XML signature objects. 
    */
   private XMLSignatureFactory signatureFactory;
+  
+  /**
+   * The URLDereferencer to dereference URLs with.
+   */
+  private URLDereferencer urlDereferencer;
   
   /**
-   * The URLDereferencerContext for dereferencing URLs.
+   * The AlgorithmMethodFactory to create {@link AlgorithmMethod} objects.
    */
-  private URLDereferencerContext dereferencerContext;
-  
-  /**
-   * The DigestMethodFactory to create {@link DigestMethod} objects.
-   */
-  private AlgorithmMethodFactory digestMethodFactory;
+  private AlgorithmMethodFactory algorithmMethodFactory;
 
   /**
    * @return the document
@@ -98,32 +98,32 @@ public class SignatureContext {
     this.signatureFactory = signatureFactory;
   }
 
-  /**
-   * @return the dereferencerContext
-   */
-  public URLDereferencerContext getDereferencerContext() {
-    return dereferencerContext;
-  }
-
-  /**
-   * @param dereferencerContext the dereferencerContext to set
-   */
-  public void setDereferencerContext(URLDereferencerContext dereferencerContext) {
-    this.dereferencerContext = dereferencerContext;
-  }
-
   /**
    * @return the digestMethodFactory
    */
   public AlgorithmMethodFactory getAlgorithmMethodFactory() {
-    return digestMethodFactory;
+    return algorithmMethodFactory;
   }
 
   /**
    * @param digestMethodFactory the digestMethodFactory to set
    */
   public void setAlgorithmMethodFactory(AlgorithmMethodFactory digestMethodFactory) {
-    this.digestMethodFactory = digestMethodFactory;
+    this.algorithmMethodFactory = digestMethodFactory;
+  }
+
+  /**
+   * @return the urlDereferencer
+   */
+  public URLDereferencer getUrlDereferencer() {
+    return urlDereferencer;
+  }
+
+  /**
+   * @param urlDereferencer the urlDereferencer to set
+   */
+  public void setUrlDereferencer(URLDereferencer urlDereferencer) {
+    this.urlDereferencer = urlDereferencer;
   }
 
 }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureLocation.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureLocation.java
index ebe50b3f..26a4aa4e 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureLocation.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureLocation.java
@@ -14,212 +14,212 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-package at.gv.egiz.bku.slcommands.impl.xsect;
-
-import java.util.Iterator;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.w3c.dom.Node;
-
-import at.buergerkarte.namespaces.securitylayer._1.SignatureInfoCreationType;
-import at.gv.egiz.bku.slexceptions.SLCommandException;
-import at.gv.egiz.slbinding.impl.SignatureLocationType;
-
-/**
- * This class implements the <code>SignatureLocation</code> of an XML-Signature
- * to be created by the security layer command <code>CreateXMLSignature</code>.
- * 
- * @author mcentner
- */
-public class SignatureLocation {
-
-  /**
-   * Logging facility.
-   */
-  private static Log log = LogFactory.getLog(SignatureLocation.class);
-  
-  /**
-   * The SignatureContext for the XML signature
-   */
-  private SignatureContext ctx;
-
-  /**
-   * The parent node for the XML signature.
-   */
-  private Node parent;
-  
-  /**
-   * The next sibling node for the XML signature.
-   */
-  private Node nextSibling;
-
-  /**
-   * Creates a new SignatureLocation with the given <code>signatureContext</code>
-   * 
-   * @param signatureContext the context for the XML signature creation
-   */
-  public SignatureLocation(SignatureContext signatureContext) {
-    this.ctx = signatureContext;
-  }
-
-  /**
-   * @return the parent node for the XML signature
-   */
-  public Node getParent() {
-    return parent;
-  }
-
-  /**
-   * @param parent the parent for the XML signature
-   */
-  public void setParent(Node parent) {
-    this.parent = parent;
-  }
-
-  /**
-   * @return the next sibling node for the XML signature
-   */
-  public Node getNextSibling() {
-    return nextSibling;
-  }
-
-  /**
-   * @param nextSibling the next sibling node for the XML signature
-   */
-  public void setNextSibling(Node nextSibling) {
-    this.nextSibling = nextSibling;
-  }
-
-  /**
-   * Configures this SignatureLocation with the information provided by the
-   * given <code>SignatureInfo</code> element.
-   * 
-   * @param signatureInfo
-   *          the <code>SignatureInfo</code> element
-   * 
-   * @throws SLCommandException
-   *           if configuring this SignatureLocation with given
-   *           <code>signatureInfo</code>fails
-   */
-  public void setSignatureInfo(SignatureInfoCreationType signatureInfo)
-      throws SLCommandException {
-
-    // evaluate signature location XPath ...
-    SignatureLocationType signatureLocation = (SignatureLocationType) signatureInfo
-        .getSignatureLocation();
-
-    NamespaceContext namespaceContext = new MOAIDWorkaroundNamespaceContext(
-        signatureLocation.getNamespaceContext());
-
-    parent = evaluateSignatureLocation(signatureInfo.getSignatureLocation()
-        .getValue(), namespaceContext, ctx.getDocument().getDocumentElement());
-
-    // ... and index
-    nextSibling = findNextSibling(parent, signatureInfo.getSignatureLocation()
-        .getIndex().intValue());
-
-  }
-  
-  /**
-   * Evaluates the given <code>xpath</code> with the document element as context node
-   * and returns the resulting node.
-   * 
-   * @param xpath the XPath expression
-   * @param nsContext the namespace context of the XPath expression
-   * @param contextNode the context node for the XPath evaluation
-   * 
-   * @return the result of evaluating the XPath expression
-   * 
-   * @throws SLCommandException
-   */
-  private Node evaluateSignatureLocation(String xpath, NamespaceContext nsContext, Node contextNode) throws SLCommandException {
-
-    Node node = null;
-    try {
-      XPathFactory xpathFactory = XPathFactory.newInstance();
-      XPath xPath = xpathFactory.newXPath();
-      xPath.setNamespaceContext(nsContext);
-      XPathExpression xpathExpr = xPath.compile(xpath);
-      node = (Node) xpathExpr.evaluate(contextNode, XPathConstants.NODE);
-    } catch (XPathExpressionException e) {
-      log.info("Failed to evaluate SignatureLocation XPath expression '" + xpath + "' on context node.", e);
-      throw new SLCommandException(4102);
-    }
-
-    if (node == null) {
-      log.info("Failed to evaluate SignatureLocation XPath expression '" + xpath + "'. Result is empty.");
-      throw new SLCommandException(4102);
-    }
-    
-    return node;
-    
-  }
-
-  /**
-   * Finds the next sibling node of the <code>parent</code>'s <code>n</code>-th child node
-   * or <code>null</code> if there is no next sibling.
-   * 
-   * @param parent the parent node
-   * @param n the index of the child node
-   * 
-   * @return the next sibling node of the node specified by <code>parent</code> and index <code>n</code>,
-   * or <code>null</code> if there is no next sibling node.
-   * 
-   * @throws SLCommandException if the <code>n</code>-th child of <code>parent</code> does not exist
-   */
-  private Node findNextSibling(Node parent, int n) throws SLCommandException {
-    return parent.getChildNodes().item(n);
-  }
-
-  /**
-   * Workaround for a missing namespace prefix declaration in MOA-ID.
-   * 
-   * @author mcentner
-   */
-  private class MOAIDWorkaroundNamespaceContext implements NamespaceContext {
-
-    private NamespaceContext namespaceContext;
-    
-    public MOAIDWorkaroundNamespaceContext(NamespaceContext namespaceContext) {
-      super();
-      this.namespaceContext = namespaceContext;
-    }
-
-    @Override
-    public String getNamespaceURI(String prefix) {
-      
-      String namespaceURI = namespaceContext.getNamespaceURI(prefix);
-      
-      if ((namespaceURI == null || XMLConstants.NULL_NS_URI.equals(namespaceURI)) && "saml".equals(prefix)) {
-        namespaceURI = "urn:oasis:names:tc:SAML:1.0:assertion";
-        log.debug("Namespace prefix '" + prefix + "' resolved to '" + namespaceURI + "' (MOA-ID Workaround).");
-      } else {
-        log.trace("Namespace prefix '" + prefix + "' resolved to '" + namespaceURI + "'.");
-      }
-      
-      return namespaceURI;
-    }
-
-    @Override
-    public String getPrefix(String namespaceURI) {
-      return namespaceContext.getPrefix(namespaceURI);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Iterator getPrefixes(String namespaceURI) {
-      return namespaceContext.getPrefixes(namespaceURI);
-    }
-    
-  }
-  
-}
+package at.gv.egiz.bku.slcommands.impl.xsect;
+
+import java.util.Iterator;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Node;
+
+import at.buergerkarte.namespaces.securitylayer._1.SignatureInfoCreationType;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+import at.gv.egiz.slbinding.impl.SignatureLocationType;
+
+/**
+ * This class implements the <code>SignatureLocation</code> of an XML-Signature
+ * to be created by the security layer command <code>CreateXMLSignature</code>.
+ * 
+ * @author mcentner
+ */
+public class SignatureLocation {
+
+  /**
+   * Logging facility.
+   */
+  private final Logger log = LoggerFactory.getLogger(SignatureLocation.class);
+  
+  /**
+   * The SignatureContext for the XML signature
+   */
+  private SignatureContext ctx;
+
+  /**
+   * The parent node for the XML signature.
+   */
+  private Node parent;
+  
+  /**
+   * The next sibling node for the XML signature.
+   */
+  private Node nextSibling;
+
+  /**
+   * Creates a new SignatureLocation with the given <code>signatureContext</code>
+   * 
+   * @param signatureContext the context for the XML signature creation
+   */
+  public SignatureLocation(SignatureContext signatureContext) {
+    this.ctx = signatureContext;
+  }
+
+  /**
+   * @return the parent node for the XML signature
+   */
+  public Node getParent() {
+    return parent;
+  }
+
+  /**
+   * @param parent the parent for the XML signature
+   */
+  public void setParent(Node parent) {
+    this.parent = parent;
+  }
+
+  /**
+   * @return the next sibling node for the XML signature
+   */
+  public Node getNextSibling() {
+    return nextSibling;
+  }
+
+  /**
+   * @param nextSibling the next sibling node for the XML signature
+   */
+  public void setNextSibling(Node nextSibling) {
+    this.nextSibling = nextSibling;
+  }
+
+  /**
+   * Configures this SignatureLocation with the information provided by the
+   * given <code>SignatureInfo</code> element.
+   * 
+   * @param signatureInfo
+   *          the <code>SignatureInfo</code> element
+   * 
+   * @throws SLCommandException
+   *           if configuring this SignatureLocation with given
+   *           <code>signatureInfo</code>fails
+   */
+  public void setSignatureInfo(SignatureInfoCreationType signatureInfo)
+      throws SLCommandException {
+
+    // evaluate signature location XPath ...
+    SignatureLocationType signatureLocation = (SignatureLocationType) signatureInfo
+        .getSignatureLocation();
+
+    NamespaceContext namespaceContext = new MOAIDWorkaroundNamespaceContext(
+        signatureLocation.getNamespaceContext());
+
+    parent = evaluateSignatureLocation(signatureInfo.getSignatureLocation()
+        .getValue(), namespaceContext, ctx.getDocument().getDocumentElement());
+
+    // ... and index
+    nextSibling = findNextSibling(parent, signatureInfo.getSignatureLocation()
+        .getIndex().intValue());
+
+  }
+  
+  /**
+   * Evaluates the given <code>xpath</code> with the document element as context node
+   * and returns the resulting node.
+   * 
+   * @param xpath the XPath expression
+   * @param nsContext the namespace context of the XPath expression
+   * @param contextNode the context node for the XPath evaluation
+   * 
+   * @return the result of evaluating the XPath expression
+   * 
+   * @throws SLCommandException
+   */
+  private Node evaluateSignatureLocation(String xpath, NamespaceContext nsContext, Node contextNode) throws SLCommandException {
+
+    Node node = null;
+    try {
+      XPathFactory xpathFactory = XPathFactory.newInstance();
+      XPath xPath = xpathFactory.newXPath();
+      xPath.setNamespaceContext(nsContext);
+      XPathExpression xpathExpr = xPath.compile(xpath);
+      node = (Node) xpathExpr.evaluate(contextNode, XPathConstants.NODE);
+    } catch (XPathExpressionException e) {
+      log.info("Failed to evaluate SignatureLocation XPath expression '{}' on context node.", xpath, e);
+      throw new SLCommandException(4102);
+    }
+
+    if (node == null) {
+      log.info("Failed to evaluate SignatureLocation XPath expression '{}'. Result is empty.", xpath);
+      throw new SLCommandException(4102);
+    }
+    
+    return node;
+    
+  }
+
+  /**
+   * Finds the next sibling node of the <code>parent</code>'s <code>n</code>-th child node
+   * or <code>null</code> if there is no next sibling.
+   * 
+   * @param parent the parent node
+   * @param n the index of the child node
+   * 
+   * @return the next sibling node of the node specified by <code>parent</code> and index <code>n</code>,
+   * or <code>null</code> if there is no next sibling node.
+   * 
+   * @throws SLCommandException if the <code>n</code>-th child of <code>parent</code> does not exist
+   */
+  private Node findNextSibling(Node parent, int n) throws SLCommandException {
+    return parent.getChildNodes().item(n);
+  }
+
+  /**
+   * Workaround for a missing namespace prefix declaration in MOA-ID.
+   * 
+   * @author mcentner
+   */
+  private class MOAIDWorkaroundNamespaceContext implements NamespaceContext {
+
+    private NamespaceContext namespaceContext;
+    
+    public MOAIDWorkaroundNamespaceContext(NamespaceContext namespaceContext) {
+      super();
+      this.namespaceContext = namespaceContext;
+    }
+
+    @Override
+    public String getNamespaceURI(String prefix) {
+      
+      String namespaceURI = namespaceContext.getNamespaceURI(prefix);
+      
+      if ((namespaceURI == null || XMLConstants.NULL_NS_URI.equals(namespaceURI)) && "saml".equals(prefix)) {
+        namespaceURI = "urn:oasis:names:tc:SAML:1.0:assertion";
+        log.debug("Namespace prefix '{}' resolved to '{}' (MOA-ID Workaround).", prefix, namespaceURI);
+      } else {
+        log.trace("Namespace prefix '{}' resolved to '{}'.", prefix, namespaceURI);
+      }
+      
+      return namespaceURI;
+    }
+
+    @Override
+    public String getPrefix(String namespaceURI) {
+      return namespaceContext.getPrefix(namespaceURI);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Iterator getPrefixes(String namespaceURI) {
+      return namespaceContext.getPrefixes(namespaceURI);
+    }
+    
+  }
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/URIDereferncerAdapter.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/URIDereferncerAdapter.java
index c94937be..5ae728b3 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/URIDereferncerAdapter.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/URIDereferncerAdapter.java
@@ -30,8 +30,7 @@ import javax.xml.crypto.URIReferenceException;
 import javax.xml.crypto.XMLCryptoContext;
 
 import at.gv.egiz.bku.utils.urldereferencer.StreamData;
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
 
 /**
  * An URIDereferencer implementation that uses an {@link URLDereferencer} to
@@ -44,17 +43,17 @@ public class URIDereferncerAdapter implements URIDereferencer {
   /**
    * The context for dereferencing.
    */
-  protected URLDereferencerContext urlDereferencerContext;
+  protected URLDereferencer dereferencer;
 
   /**
    * Creates a new URIDereferencerAdapter instance with the given
    * <code>urlDereferencerContext</code>.
    * 
-   * @param urlDereferencerContext the context to be used for dereferencing
+   * @param urlDereferencer the context to be used for dereferencing
    */
-  public URIDereferncerAdapter(URLDereferencerContext urlDereferencerContext) {
+  public URIDereferncerAdapter(URLDereferencer urlDereferencer) {
     super();
-    this.urlDereferencerContext = urlDereferencerContext;
+    this.dereferencer = urlDereferencer;
   }
 
   /* (non-Javadoc)
@@ -78,10 +77,9 @@ public class URIDereferncerAdapter implements URIDereferencer {
     
     if (uri.isAbsolute()) {
 
-      URLDereferencer dereferencer = URLDereferencer.getInstance();
       StreamData streamData;
       try {
-        streamData = dereferencer.dereference(uriString, urlDereferencerContext);
+        streamData = dereferencer.dereference(uriString);
       } catch (IOException e) {
         throw new URIReferenceException(e.getMessage(), e);
       }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLBindingException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLBindingException.java
index 3f1732ba..eff9aec5 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLBindingException.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLBindingException.java
@@ -21,6 +21,8 @@ package at.gv.egiz.bku.slexceptions;
  */
 public class SLBindingException extends SLException {
 
+  private static final long serialVersionUID = 1L;
+
   public SLBindingException(int errorCode) {
     super(errorCode);
   }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCanceledException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCanceledException.java
index 8136a093..801526dc 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCanceledException.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCanceledException.java
@@ -19,6 +19,8 @@ package at.gv.egiz.bku.slexceptions;
 public class SLCanceledException extends
     at.gv.egiz.bku.slexceptions.SLException {
 
+  private static final long serialVersionUID = 1L;
+
   public SLCanceledException(int errorCode, String msg, Object[] args) {
     super(errorCode, msg, args);
     // TODO Auto-generated constructor stub
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLException.java
index 4b541deb..854c1658 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLException.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLException.java
@@ -82,7 +82,14 @@ public class SLException extends Exception {
     
     return localizedMessage;
     
+  }
+
+  /* (non-Javadoc)
+   * @see java.lang.Throwable#getMessage()
+   */
+  @Override
+  public String getMessage() {
+    return getLocalizedMessage();
   }
-  
 
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRequestException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRequestException.java
index 548732e6..fd02cff7 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRequestException.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRequestException.java
@@ -18,6 +18,8 @@ package at.gv.egiz.bku.slexceptions;
 
 public class SLRequestException extends SLException {
 
+  private static final long serialVersionUID = 1L;
+
   public SLRequestException(int errorCode) {
     super(errorCode);
     // TODO Auto-generated constructor stub
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRuntimeException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRuntimeException.java
index d09ca418..aa8cd5b5 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRuntimeException.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRuntimeException.java
@@ -18,6 +18,8 @@ package at.gv.egiz.bku.slexceptions;
 
 public class SLRuntimeException extends RuntimeException {
 
+  private static final long serialVersionUID = 1L;
+
   public SLRuntimeException(String message, Throwable cause) {
     super(message, cause);
   }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLViewerException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLViewerException.java
index 853328d5..1bfad289 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLViewerException.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLViewerException.java
@@ -18,6 +18,8 @@ package at.gv.egiz.bku.slexceptions;
 
 public class SLViewerException extends SLException {
 
+  private static final long serialVersionUID = 1L;
+
   public SLViewerException(int errorCode) {
     super(errorCode);
   }
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurableHostnameVerifier.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurableHostnameVerifier.java
new file mode 100644
index 00000000..c2f64994
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurableHostnameVerifier.java
@@ -0,0 +1,77 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.spring;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+
+import org.apache.commons.configuration.Configuration;
+
+import at.gv.egiz.bku.conf.MoccaConfigurationFacade;
+
+public class ConfigurableHostnameVerifier implements HostnameVerifier {
+
+  /**
+   * The configuration facade.
+   */
+  protected final ConfigurationFacade configurationFacade = new ConfigurationFacade();
+  
+  public class ConfigurationFacade implements MoccaConfigurationFacade {
+    
+    private Configuration configuration;
+    
+    public static final String SSL_DISSABLE_HOSTNAME_VERIFICATION = "SSL.disableHostnameVerification";
+    
+    public static final String SSL_DISSABLE_ALL_CHECKS = "SSL.disableAllChecks";
+    
+    public boolean disableSslHostnameVerification() {
+      return configuration.getBoolean(SSL_DISSABLE_HOSTNAME_VERIFICATION, false);
+    }
+    
+    public boolean disableAllSslChecks() {
+      return configuration.getBoolean(SSL_DISSABLE_ALL_CHECKS, false);
+    }
+    
+  }
+
+  /**
+   * @return the configuration
+   */
+  public Configuration getConfiguration() {
+    return configurationFacade.configuration;
+  }
+
+  /**
+   * @param configuration the configuration to set
+   */
+  public void setConfiguration(Configuration configuration) {
+    configurationFacade.configuration = configuration;
+  }
+
+  
+  @Override
+  public boolean verify(String hostname, SSLSession session) {
+    if (configurationFacade.disableAllSslChecks() || configurationFacade.disableSslHostnameVerification()) {
+      return true;
+    } else {
+      return HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session);
+    }
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurationFactoryBean.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurationFactoryBean.java
new file mode 100644
index 00000000..a6a7c346
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurationFactoryBean.java
@@ -0,0 +1,172 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.spring;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.commons.configuration.CompositeConfiguration;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.MapConfiguration;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+
+import at.gv.egiz.bku.slcommands.impl.CreateXMLSignatureCommandImpl;
+
+/**
+ * This is a {@link FactoryBean} for the creation of a {@link Configuration}.
+ * 
+ * @author mcentner
+ */
+public class ConfigurationFactoryBean implements FactoryBean, ResourceLoaderAware {
+  
+  protected static final Logger log = LoggerFactory.getLogger(ConfigurationFactoryBean.class);
+
+  public static final String DEFAULT_CONFIG = "/WEB-INF/conf/configuration.xml";
+  
+  public static final String MOCCA_IMPLEMENTATIONNAME_PROPERTY = "ProductName";
+
+  public static final String MOCCA_IMPLEMENTATIONVERSION_PROPERTY = "ProductVersion";
+  
+  public static final String SIGNATURE_LAYOUT_PROPERTY = "SignatureLayout";
+  
+  /**
+   * The URL of the configuration file.
+   */
+  protected Resource configurationResource;
+  
+  /**
+   * The ResourceLoader.
+   */
+  protected ResourceLoader resourceLoader;
+  
+  @Override
+  public void setResourceLoader(ResourceLoader resourceLoader) {
+    this.resourceLoader = resourceLoader;
+  }
+
+  /**
+   * @return the configurationURL
+   */
+  public Resource getConfigurationResource() {
+    return configurationResource;
+  }
+
+  /**
+   * @param configurationResource the configurationURL to set
+   */
+  public void setConfigurationResource(Resource configurationResource) {
+    this.configurationResource = configurationResource;
+  }
+
+  protected Configuration getDefaultConfiguration()
+      throws ConfigurationException, IOException {
+    Resource resource = resourceLoader.getResource(DEFAULT_CONFIG);
+    XMLConfiguration xmlConfiguration = new XMLConfiguration();
+    xmlConfiguration.load(resource.getInputStream());
+    xmlConfiguration.setURL(resource.getURL());
+    return xmlConfiguration;
+  }
+  
+  protected Configuration getVersionConfiguration() throws IOException {
+    
+    Map<String, String> map = new HashMap<String, String>();
+    map.put(MOCCA_IMPLEMENTATIONNAME_PROPERTY, "MOCCA");
+    
+    // implementation version
+    String version = null;
+    try {
+      Resource resource = resourceLoader.getResource("META-INF/MANIFEST.MF");
+      Manifest properties = new Manifest(resource.getInputStream());
+      Attributes attributes = properties.getMainAttributes();
+      // TODO: replace by Implementation-Version ?
+      version = attributes.getValue("Implementation-Build");
+    } catch (Exception e) {
+      log.warn("Failed to get implemenation version from manifest. {}", e.getMessage());
+    }
+    
+    if (version == null) {
+      version="UNKNOWN";
+    }
+    map.put(MOCCA_IMPLEMENTATIONVERSION_PROPERTY, version);
+    
+    // signature layout
+    try {
+      String classContainer = CreateXMLSignatureCommandImpl.class.getProtectionDomain()
+          .getCodeSource().getLocation().toString();
+      URL manifestUrl = new URL("jar:" + classContainer
+          + "!/META-INF/MANIFEST.MF");
+      Manifest manifest = new Manifest(manifestUrl.openStream());
+      Attributes attributes = manifest.getMainAttributes();
+      String signatureLayout = attributes.getValue("SignatureLayout");
+      if (signatureLayout != null) {
+        map.put(SIGNATURE_LAYOUT_PROPERTY, signatureLayout);
+      }
+    } catch (Exception e) {
+      log.warn("Failed to get signature layout from manifest.", e);
+    }
+    
+    
+    return new MapConfiguration(map);
+    
+  }
+  
+  @Override
+  public Object getObject() throws Exception {
+    
+    log.info("Configuration resource is {}.", configurationResource);
+    
+    CompositeConfiguration configuration;
+    if (configurationResource == null) {
+      // initialize default configuration
+      log.warn("Initializing with default configuration.");
+      configuration = new CompositeConfiguration();
+    } else {
+      // initialize with writable configuration
+      URL url = configurationResource.getURL();
+      XMLConfiguration writableConfiguration = new XMLConfiguration(url);
+      configuration = new CompositeConfiguration(writableConfiguration);
+      log.info("Initialized with configuration from '{}'.", url);
+    }
+    configuration.addConfiguration(getDefaultConfiguration());
+    configuration.addConfiguration(getVersionConfiguration());
+    return configuration;
+  }
+
+  @Override
+  public Class<?> getObjectType() {
+    return Configuration.class;
+  }
+
+  @Override
+  public boolean isSingleton() {
+    return true;
+  }
+
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKIProfileFactoryBean.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKIProfileFactoryBean.java
new file mode 100644
index 00000000..97a0d872
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKIProfileFactoryBean.java
@@ -0,0 +1,235 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.spring;
+
+import iaik.logging.LogConfigurationException;
+import iaik.logging.LoggerConfig;
+import iaik.logging.impl.TransactionIdImpl;
+import iaik.pki.DefaultPKIConfiguration;
+import iaik.pki.DefaultPKIProfile;
+import iaik.pki.PKIException;
+import iaik.pki.PKIFactory;
+import iaik.pki.PKIProfile;
+import iaik.pki.revocation.RevocationSourceTypes;
+import iaik.pki.store.certstore.CertStoreParameters;
+import iaik.pki.store.certstore.directory.DefaultDirectoryCertStoreParameters;
+import iaik.pki.store.truststore.DefaultTrustStoreProfile;
+import iaik.pki.store.truststore.TrustStoreProfile;
+import iaik.pki.store.truststore.TrustStoreTypes;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Properties;
+
+import org.apache.commons.configuration.CompositeConfiguration;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.FileConfiguration;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+
+import at.gv.egiz.bku.conf.IAIKLogAdapterFactory;
+import at.gv.egiz.bku.conf.MoccaConfigurationFacade;
+
+public class PKIProfileFactoryBean implements FactoryBean, ResourceLoaderAware {
+
+  /**
+   * The configuration facade.
+   */
+  protected final ConfigurationFacade configurationFacade = new ConfigurationFacade();
+
+  public class ConfigurationFacade implements MoccaConfigurationFacade {
+    
+    private Configuration configuration;
+    
+    public static final String SSL_CERT_DIRECTORY = "SSL.certDirectory";
+    
+    public static final String SSL_CERT_DIRECTORY_DEFAULT = "classpath:at/gv/egiz/bku/certs/certStore";
+    
+    public static final String SSL_CA_DIRECTORY = "SSL.caDirectory";
+    
+    public static final String SSL_CA_DIRECTORY_DEFAULT = "classpath:at/gv/egiz/bku/certs/trustStore";
+    
+    public URL getCertDirectory() throws MalformedURLException {
+      return getURL(SSL_CERT_DIRECTORY);
+    }
+    
+    public URL getCaDirectory() throws MalformedURLException {
+      return getURL(SSL_CA_DIRECTORY);
+    }
+    
+    private URL getURL(String key) throws MalformedURLException {
+      String url = configuration.getString(key);
+      if (url == null || url.isEmpty()) {
+        return null;
+      }
+      return new URL(getBasePath(key), configuration.getString(key));
+    }
+
+    private URL getBasePath(String key) {
+      Configuration configuration = this.configuration;
+      if (configuration instanceof CompositeConfiguration) {
+        CompositeConfiguration compositeConfiguration = (CompositeConfiguration) configuration;
+        for (int i = 0; i < compositeConfiguration.getNumberOfConfigurations(); i++) {
+          if (compositeConfiguration.getConfiguration(i).containsKey(key)) {
+            configuration = compositeConfiguration.getConfiguration(i);
+            break;
+          }
+        }
+      }
+      if (configuration instanceof FileConfiguration) {
+        return ((FileConfiguration) configuration).getURL();
+      }
+      return null;
+    }
+    
+  }
+
+  
+  private ResourceLoader resourceLoader;
+  
+  protected String trustProfileId;
+
+  @Override
+  public void setResourceLoader(ResourceLoader loader) {
+    this.resourceLoader = loader;
+  }
+  
+  /**
+   * @return the configuration
+   */
+  public Configuration getConfiguration() {
+    return configurationFacade.configuration;
+  }
+
+  /**
+   * @param configuration the configuration to set
+   */
+  public void setConfiguration(Configuration configuration) {
+    configurationFacade.configuration = configuration;
+  }
+
+  /**
+   * @return the trustProfileId
+   */
+  public String getTrustProfileId() {
+    return trustProfileId;
+  }
+
+  /**
+   * @param trustProfileId the trustProfileId to set
+   */
+  public void setTrustProfileId(String trustProfileId) {
+    this.trustProfileId = trustProfileId;
+  }
+
+  protected File getDirectory(String url) throws IOException {
+    Resource resource = resourceLoader.getResource(url);
+    File path = resource.getFile();
+    if (!path.exists() && !path.isDirectory()) {
+      throw new IOException("URL '" + url + "' is not a directory.");
+    }
+    return path;
+  }
+  
+  protected void configureIAIKLogging() {
+    // initialize IAIK logging for PKI module
+    iaik.logging.LogFactory.configure(new LoggerConfig() {
+      
+      @Override
+      public Properties getProperties() throws LogConfigurationException {
+        return null;
+      }
+      
+      @Override
+      public String getNodeId() {
+        return "pki";
+      }
+      
+      @Override
+      public String getFactory() {
+        return IAIKLogAdapterFactory.class.getName();
+      }
+    });
+  }
+  
+  protected void configurePkiFactory() throws MalformedURLException, PKIException, IOException {
+    
+    URL url = configurationFacade.getCertDirectory();
+    File certDirectory = (url != null) 
+        ? getDirectory(url.toString())
+        : getDirectory(ConfigurationFacade.SSL_CERT_DIRECTORY_DEFAULT);
+    
+    CertStoreParameters[] certStoreParameters = { new DefaultDirectoryCertStoreParameters(
+        "CS", certDirectory.getAbsolutePath(), true, false) };
+    
+    DefaultPKIConfiguration pkiConfiguration = new DefaultPKIConfiguration(certStoreParameters);
+  
+    
+    PKIFactory pkiFactory = PKIFactory.getInstance();
+    pkiFactory.configure(pkiConfiguration, new TransactionIdImpl("Configure-PKI"));
+  }
+
+  protected TrustStoreProfile createDirectoryTrustStoreProfile() throws MalformedURLException, IOException {
+    
+    URL url = configurationFacade.getCaDirectory();
+    File caDirectory = (url != null) 
+        ? getDirectory(url.toString())
+        : getDirectory(ConfigurationFacade.SSL_CA_DIRECTORY_DEFAULT);        
+    
+    return new DefaultTrustStoreProfile(trustProfileId,
+        TrustStoreTypes.DIRECTORY, caDirectory.getAbsolutePath());
+    
+  }
+  
+  @Override
+  public Object getObject() throws Exception {
+    
+    configureIAIKLogging();
+
+    PKIFactory pkiFactory = PKIFactory.getInstance();
+    
+    if (!pkiFactory.isAlreadyConfigured()) {
+      configurePkiFactory();
+    }
+
+    TrustStoreProfile trustProfile = createDirectoryTrustStoreProfile();
+
+    DefaultPKIProfile pkiProfile = new DefaultPKIProfile(trustProfile);
+    
+    pkiProfile.setAutoAddCertificates(true);
+    pkiProfile.setPreferredServiceOrder(new String[] {
+        RevocationSourceTypes.OCSP, RevocationSourceTypes.CRL });
+    
+    return pkiProfile;
+  }
+
+  @Override
+  public Class<?> getObjectType() {
+    return PKIProfile.class;
+  }
+
+  @Override
+  public boolean isSingleton() {
+    return false;
+  }
+  
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKITrustManager.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKITrustManager.java
new file mode 100644
index 00000000..36fdcd06
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKITrustManager.java
@@ -0,0 +1,173 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.spring;
+
+import iaik.logging.TransactionId;
+import iaik.pki.PKIException;
+import iaik.pki.PKIFactory;
+import iaik.pki.PKIModule;
+import iaik.pki.PKIProfile;
+import iaik.pki.store.truststore.TrustStore;
+import iaik.pki.store.truststore.TrustStoreException;
+import iaik.pki.store.truststore.TrustStoreFactory;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.commons.configuration.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+import at.gv.egiz.bku.conf.MoccaConfigurationFacade;
+
+public class PKITrustManager implements X509TrustManager {
+  
+  Logger log = LoggerFactory.getLogger(PKITrustManager.class);
+
+  protected PKIProfile pkiProfile;
+
+  /**
+   * The configuration facade.
+   */
+  protected final ConfigurationFacade configurationFacade = new ConfigurationFacade();
+  
+  public class ConfigurationFacade implements MoccaConfigurationFacade {
+    
+    private Configuration configuration;
+    
+    public static final String SSL_DISSABLE_ALL_CHECKS = "SSL.disableAllChecks";
+    
+    public boolean disableAllSslChecks() {
+      return configuration.getBoolean(SSL_DISSABLE_ALL_CHECKS, false);
+    }
+    
+  }
+
+  /**
+   * @return the configuration
+   */
+  public Configuration getConfiguration() {
+    return configurationFacade.configuration;
+  }
+
+  /**
+   * @param configuration the configuration to set
+   */
+  public void setConfiguration(Configuration configuration) {
+    configurationFacade.configuration = configuration;
+  }
+  
+  /**
+   * @return the pkiProfile
+   */
+  public PKIProfile getPkiProfile() {
+    return pkiProfile;
+  }
+
+  /**
+   * @param pkiProfile the pkiProfile to set
+   */
+  public void setPkiProfile(PKIProfile pkiProfile) {
+    this.pkiProfile = pkiProfile;
+  }
+
+  @Override
+  public void checkClientTrusted(X509Certificate[] chain, String authType)
+      throws CertificateException {
+    checkServerTrusted(chain, authType);
+  }
+
+  @Override
+  public void checkServerTrusted(X509Certificate[] chain, String authType)
+      throws CertificateException {
+
+    if (pkiProfile == null) {
+      throw new CertificateException("No PKI profile set. Configuration error.");
+    }
+    
+    if (configurationFacade.disableAllSslChecks()) {
+      log.warn("SSL certificate validation disabled. " +
+      		"Accepted certificate {}.", chain[0].getSubjectDN());
+    } else {
+
+      iaik.x509.X509Certificate[] certs = convertCerts(chain);
+      
+      TransactionId tid = new MDCTransactionId();    
+      try {
+        PKIModule pkiModule = PKIFactory.getInstance().getPKIModule(pkiProfile);
+        if (!pkiModule.validateCertificate(new Date(), certs[0], certs, null,
+            tid).isCertificateValid()) {
+          throw new CertificateException("Certificate not valid.");
+        }
+      } catch (PKIException e) {
+        log.warn("Failed to validate certificate.", e);
+        throw new CertificateException("Failed to validate certificate. " + e.getMessage());
+      }
+      
+    }
+
+  }
+
+  @Override
+  public X509Certificate[] getAcceptedIssuers() {
+    
+    if (pkiProfile == null) {
+      log.warn("No PKI profile set. Configuration error.");
+      return new X509Certificate[] {};
+    }
+    
+    TransactionId tid = new MDCTransactionId();
+    
+    try {
+      
+      TrustStore trustStore = TrustStoreFactory.getInstance(pkiProfile.getTrustStoreProfile(), tid);
+      return (X509Certificate[]) trustStore.getTrustedCertificates(tid).toArray();
+      
+    } catch (TrustStoreException e) {
+      log.warn("Failed to get list of accepted issuers.", e);
+      return new X509Certificate[] {};
+    }
+
+  }
+
+  private static iaik.x509.X509Certificate[] convertCerts(
+      X509Certificate[] certs) throws CertificateException {
+    iaik.x509.X509Certificate[] retVal = new iaik.x509.X509Certificate[certs.length];
+    int i = 0;
+    for (X509Certificate cert : certs) {
+      if (cert instanceof iaik.x509.X509Certificate) {
+        retVal[i++] = (iaik.x509.X509Certificate) cert;
+      } else {
+        retVal[i++] = new iaik.x509.X509Certificate(cert.getEncoded());
+      }
+    }
+    return retVal;
+  }
+
+  private static class MDCTransactionId implements TransactionId {
+    @Override
+    public String getLogID() {
+      String sessionId = MDC.get("SessionId");
+      return (sessionId != null) ? sessionId : "PKITrustManager"; 
+    }
+  }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/SSLSocketFactoryBean.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/SSLSocketFactoryBean.java
new file mode 100644
index 00000000..f6dbddd6
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/SSLSocketFactoryBean.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.spring;
+
+import iaik.pki.PKIProfile;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+import org.apache.commons.configuration.Configuration;
+import org.springframework.beans.factory.FactoryBean;
+
+import at.gv.egiz.bku.conf.MoccaConfigurationFacade;
+
+public class SSLSocketFactoryBean implements FactoryBean {
+  
+  protected PKIProfile pkiProfile;
+  
+  /**
+   * The configuration facade.
+   */
+  protected final ConfigurationFacade configurationFacade = new ConfigurationFacade();
+  
+  public class ConfigurationFacade implements MoccaConfigurationFacade {
+    
+    private Configuration configuration;
+    
+    public static final String SSL_PROTOCOL = "SSL.sslProtocol";
+    
+    public static final String SSL_DISSABLE_ALL_CHECKS = "SSL.disableAllChecks";
+    
+    public String getSslProtocol() {
+      return configuration.getString(SSL_PROTOCOL, "TLS");
+    }
+    
+    public boolean disableAllSslChecks() {
+      return configuration.getBoolean(SSL_DISSABLE_ALL_CHECKS, false);
+    }
+    
+  }
+
+  /**
+   * @return the configuration
+   */
+  public Configuration getConfiguration() {
+    return configurationFacade.configuration;
+  }
+
+  /**
+   * @param configuration the configuration to set
+   */
+  public void setConfiguration(Configuration configuration) {
+    configurationFacade.configuration = configuration;
+  }
+
+  /**
+   * @return the pkiProfile
+   */
+  public PKIProfile getPkiProfile() {
+    return pkiProfile;
+  }
+
+  /**
+   * @param pkiProfile the pkiProfile to set
+   */
+  public void setPkiProfile(PKIProfile pkiProfile) {
+    this.pkiProfile = pkiProfile;
+  }
+  
+  @Override
+  public Object getObject() throws Exception {
+    
+    PKITrustManager pkiTrustManager = new PKITrustManager();
+    pkiTrustManager.setConfiguration(configurationFacade.configuration);
+    pkiTrustManager.setPkiProfile(pkiProfile);
+    
+    SSLContext sslContext = SSLContext.getInstance(configurationFacade.getSslProtocol());
+    sslContext.init(null, new TrustManager[] {pkiTrustManager}, null);
+    
+    return sslContext.getSocketFactory();
+  }
+
+  @Override
+  public Class<?> getObjectType() {
+    return SSLSocketFactory.class;
+  }
+
+  @Override
+  public boolean isSingleton() {
+    return false;
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/SecurityManagerFactoryBean.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/SecurityManagerFactoryBean.java
new file mode 100644
index 00000000..4e9e4d76
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/SecurityManagerFactoryBean.java
@@ -0,0 +1,102 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.bku.spring;
+
+import org.apache.commons.configuration.Configuration;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+
+import at.gv.egiz.bku.accesscontroller.SecurityManagerFacade;
+
+public class SecurityManagerFactoryBean implements ResourceLoaderAware,
+    FactoryBean {
+
+  protected ResourceLoader resourceLoader;
+  
+  protected ConfigurationFacade configurationFacade = new ConfigurationFacade(); 
+  
+  public class ConfigurationFacade {
+    
+    protected ConfigurationFacade() {
+    }
+    
+    public static final String ACCESSCONTROLLER_POLICYRESOURCE = "AccessController.PolicyResource";
+
+    public static final String ACCESSCONTROLLER_DEFAULT_POLICYRESOURCE = "classpath:/at/gv/egiz/bku/accesscontrol/config/accessControlConfig.xml";
+
+    public static final String ACCESSCONTROLLER_ACCEPTNOMATCH = "AccessController.AcceptNoMatch";
+
+    public static final boolean ACCESSCONTROLLER_DEFAULT_ACCEPTNOMATCH = false;
+    
+    protected String getPolicyResource() {
+      return configuration.getString(ACCESSCONTROLLER_POLICYRESOURCE, ACCESSCONTROLLER_DEFAULT_POLICYRESOURCE);
+    }
+    
+    protected boolean getAcceptNoMatch() {
+      return configuration.getBoolean(ACCESSCONTROLLER_ACCEPTNOMATCH, ACCESSCONTROLLER_DEFAULT_ACCEPTNOMATCH);
+    }
+    
+  }
+  
+  protected Configuration configuration;
+  
+  /**
+   * @return the configuration
+   */
+  public Configuration getConfiguration() {
+    return configuration;
+  }
+
+  /**
+   * @param configuration the configuration to set
+   */
+  public void setConfiguration(Configuration configuration) {
+    this.configuration = configuration;
+  }
+
+  @Override
+  public void setResourceLoader(ResourceLoader resourceLoader) {
+    this.resourceLoader = resourceLoader;
+  }
+
+  @Override
+  public Object getObject() throws Exception {
+    
+    SecurityManagerFacade sm = new SecurityManagerFacade();
+    sm.setAllowUnmatched(configurationFacade.getAcceptNoMatch());
+
+    Resource policyResource = resourceLoader.getResource(configurationFacade.getPolicyResource());
+    sm.init(policyResource.getInputStream());
+
+    return sm;
+    
+  }
+
+  @Override
+  public Class<?> getObjectType() {
+    return SecurityManagerFacade.class;
+  }
+
+  @Override
+  public boolean isSingleton() {
+    return true;
+  }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ResourceFontLoader.java b/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ResourceFontLoader.java
index 8cab581d..91dfc9da 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ResourceFontLoader.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ResourceFontLoader.java
@@ -19,8 +19,8 @@ package at.gv.egiz.bku.viewer;
 import at.gv.egiz.bku.gui.viewer.FontProviderException;
 import at.gv.egiz.bku.gui.viewer.FontProvider;
 import java.awt.Font;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Loads font(s) as classpath resource.
@@ -31,7 +31,7 @@ public class ResourceFontLoader implements FontProvider {
   
   public static final String FONT_RESOURCE = "DejaVuLGCSansMono.ttf";
 
-  protected final static Log log = LogFactory.getLog(ResourceFontLoader.class);
+  private final Logger log = LoggerFactory.getLogger(ResourceFontLoader.class);
 
   /** TextValidator and (local) SecureViewerDialog (see LocalStalFactory) use ResourceFontLoader, load resource only once  */
   protected static Font font;
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ValidatorFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ValidatorFactory.java
index ad9bf6bb..c5a90a61 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ValidatorFactory.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ValidatorFactory.java
@@ -26,15 +26,15 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Properties;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ValidatorFactory {
   
   /**
    * Logging facility.
    */
-  protected static Log log = LogFactory.getLog(ValidatorFactory.class);
+  private final Logger log = LoggerFactory.getLogger(ValidatorFactory.class);
   
   private static final Class<Validator> VALIDATOR_CLASS = Validator.class;
   
@@ -93,7 +93,7 @@ public class ValidatorFactory {
       try {
         properties.load(url.openStream());
       } catch (IOException e) {
-        log.error("Failed to load service properties " + url.toExternalForm());
+        log.error("Failed to load service properties {}.", url.toExternalForm());
         continue;
       }
       String className = properties.getProperty(mimeType);
@@ -124,22 +124,22 @@ public class ValidatorFactory {
       return (Validator) implConstructor.newInstance((Object[])null);
     } catch (InvocationTargetException ex) {
       //ex from constructor
-      log.error("Failed to initialize validator class '" + className + "': " + ex.getCause().getMessage(), ex.getCause());
+      log.error("Failed to initialize validator class '{}'.", className, ex.getCause());
       throw ex;
     } catch (NoSuchMethodException ex) {
-      log.error("Validator class '" + className + "' has no nullary constructor", ex);
+      log.error("Validator class '{}' has no nullary constructor.", className, ex);
       throw ex;
     } catch (ClassNotFoundException e) {
-      log.error("Validator class '" + className + "' not found.", e);
+      log.error("Validator class '{}' not found.", className, e);
       throw e;
     } catch (InstantiationException e) {
-      log.error("Faild to initialize validator class '" + className + "'.", e);
+      log.error("Faild to initialize validator class '{}'.", className, e);
       throw e;
     } catch (IllegalAccessException e) {
-      log.error("Faild to initialize validator class '" + className + "'.", e);
+      log.error("Faild to initialize validator class '{}'.", className, e);
       throw e;
     } catch (ClassCastException e) {
-      log.error("Class '" + className + "' is not a validator implementation.", e);
+      log.error("Class '{}' is not a validator implementation.", className, e);
       throw e;
     }
     
@@ -168,7 +168,7 @@ public class ValidatorFactory {
         
       };
     } catch (IOException e) {
-      log.error("Failed to enumerate resources " + SERVICE_ID);
+      log.error("Failed to enumerate resources {}.", SERVICE_ID);
       List<URL> list = Collections.emptyList(); 
       return list.iterator();
     }
-- 
cgit v1.2.3