keycloak-aplcache

Changes

pom.xml 2(+1 -1)

saml/pom.xml 19(+0 -19)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/LogoutRequestType.java 188(+0 -188)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/ManageNameIDRequestType.java 158(+0 -158)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/NameIDMappingRequestType.java 135(+0 -135)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/NameIDMappingResponseType.java 90(+0 -90)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/NameIDPolicyType.java 100(+0 -100)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/package-info.java 23(+0 -23)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/RequestAbstractType.java 149(+0 -149)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/RequestedAuthnContextType.java 135(+0 -135)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/ResponseType.java 135(+0 -135)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/ScopingType.java 125(+0 -125)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusCodeType.java 89(+0 -89)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusResponseType.java 185(+0 -185)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusType.java 108(+0 -108)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/SubjectQueryAbstractType.java 63(+0 -63)

saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/TerminateType.java 38(+0 -38)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/CanonicalizationMethodType.java 67(+0 -67)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/DigestMethodType.java 67(+0 -67)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/KeyInfoType.java 86(+0 -86)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/KeyValueType.java 44(+0 -44)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/ManifestType.java 84(+0 -84)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/ObjectType.java 123(+0 -123)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/package-info.java 19(+0 -19)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/PGPDataType.java 71(+0 -71)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/ReferenceType.java 160(+0 -160)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/RetrievalMethodType.java 101(+0 -101)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/RSAKeyValueType.java 164(+0 -164)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignatureMethodType.java 86(+0 -86)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignaturePropertiesType.java 85(+0 -85)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignaturePropertyType.java 95(+0 -95)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignatureType.java 144(+0 -144)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignatureValueType.java 77(+0 -77)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignedInfoType.java 125(+0 -125)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SPKIDataType.java 65(+0 -65)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/TransformsType.java 65(+0 -65)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/TransformType.java 82(+0 -82)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/X509CertificateType.java 31(+0 -31)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/X509DataType.java 71(+0 -71)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/X509IssuerSerialType.java 82(+0 -82)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/AgreementMethodType.java 87(+0 -87)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/CipherDataType.java 80(+0 -80)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/CipherReferenceType.java 78(+0 -78)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptedDataType.java 38(+0 -38)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptedKeyType.java 102(+0 -102)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptedType.java 204(+0 -204)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptionMethodType.java 89(+0 -89)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptionPropertiesType.java 84(+0 -84)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptionPropertyType.java 109(+0 -109)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/package-info.java 19(+0 -19)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/ReferenceList.java 82(+0 -82)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/ReferenceType.java 68(+0 -68)

saml/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/TransformsType.java 69(+0 -69)

saml/saml-core/src/main/java/org/keycloak/saml/common/constants/GeneralConstants.java 155(+0 -155)

saml/saml-core/src/main/java/org/keycloak/saml/common/constants/JBossSAMLConstants.java 80(+0 -80)

saml/saml-core/src/main/java/org/keycloak/saml/common/constants/JBossSAMLURIConstants.java 132(+0 -132)

saml/saml-core/src/main/java/org/keycloak/saml/common/constants/PicketLinkCommonConstants.java 30(+0 -30)

saml/saml-core/src/main/java/org/keycloak/saml/common/constants/SAMLAuthenticationContextClass.java 63(+0 -63)

saml/saml-core/src/main/java/org/keycloak/saml/common/constants/WSTrustConstants.java 246(+0 -246)

saml/saml-core/src/main/java/org/keycloak/saml/common/ErrorCodes.java 206(+0 -206)

saml/saml-core/src/main/java/org/keycloak/saml/common/exceptions/ConfigurationException.java 45(+0 -45)

saml/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/AssertionExpiredException.java 53(+0 -53)

saml/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/IssueInstantMissingException.java 45(+0 -45)

saml/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/IssuerNotTrustedException.java 45(+0 -45)

saml/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/SignatureValidationException.java 44(+0 -44)

saml/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/WSTrustException.java 65(+0 -65)

saml/saml-core/src/main/java/org/keycloak/saml/common/exceptions/NotImplementedException.java 36(+0 -36)

saml/saml-core/src/main/java/org/keycloak/saml/common/exceptions/ParsingException.java 63(+0 -63)

saml/saml-core/src/main/java/org/keycloak/saml/common/exceptions/PicketLinkException.java 45(+0 -45)

saml/saml-core/src/main/java/org/keycloak/saml/common/exceptions/ProcessingException.java 45(+0 -45)

saml/saml-core/src/main/java/org/keycloak/saml/common/exceptions/TrustKeyConfigurationException.java 43(+0 -43)

saml/saml-core/src/main/java/org/keycloak/saml/common/exceptions/TrustKeyProcessingException.java 43(+0 -43)

saml/saml-core/src/main/java/org/keycloak/saml/common/parsers/AbstractParser.java 141(+0 -141)

saml/saml-core/src/main/java/org/keycloak/saml/common/parsers/ParserNamespaceSupport.java 54(+0 -54)

saml/saml-core/src/main/java/org/keycloak/saml/common/PicketLinkLoggerFactory.java 55(+0 -55)

saml/saml-core/src/main/java/org/keycloak/saml/common/util/SecurityActions.java 221(+0 -221)

saml/saml-core/src/main/java/org/keycloak/saml/common/util/StaxUtil.java 447(+0 -447)

saml/saml-core/src/main/java/org/keycloak/saml/common/util/StringUtil.java 199(+0 -199)

saml/saml-core/src/main/java/org/keycloak/saml/common/util/SystemPropertiesUtil.java 64(+0 -64)

saml/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/request/SAML2Request.java 336(+0 -336)

saml/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/request/SecurityActions.java 166(+0 -166)

saml/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/response/SecurityActions.java 122(+0 -122)

saml/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/sig/SAML2Signature.java 238(+0 -238)

saml/saml-core/src/main/java/org/keycloak/saml/processing/api/util/DeflateUtil.java 80(+0 -80)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/constants/AttributeConstants.java 34(+0 -34)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/constants/PicketLinkFederationConstants.java 53(+0 -53)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/AbstractDescriptorParser.java 66(+0 -66)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/SAMLEntitiesDescriptorParser.java 123(+0 -123)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11AssertionParser.java 178(+0 -178)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11RequestParser.java 116(+0 -116)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11ResponseParser.java 189(+0 -189)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11SubjectParser.java 114(+0 -114)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLArtifactResolveParser.java 90(+0 -90)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLArtifactResponseParser.java 111(+0 -111)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAssertionParser.java 174(+0 -174)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAttributeQueryParser.java 92(+0 -92)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAuthNRequestParser.java 212(+0 -212)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLConditionsParser.java 174(+0 -174)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParser.java 129(+0 -129)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLRequestAbstractParser.java 109(+0 -109)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLResponseParser.java 108(+0 -108)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSloRequestParser.java 119(+0 -119)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSloResponseParser.java 78(+0 -78)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLStatusResponseTypeParser.java 187(+0 -187)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSubjectParser.java 206(+0 -206)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SecurityActions.java 94(+0 -94)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/SAML11Constants.java 131(+0 -131)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/writers/BaseSAML11Writer.java 48(+0 -48)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/writers/SAML11RequestWriter.java 171(+0 -171)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/writers/SAML11ResponseWriter.java 137(+0 -137)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/common/IDGenerator.java 58(+0 -58)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/common/SAMLDocumentHolder.java 64(+0 -64)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/constants/X500SAMLProfileConstants.java 154(+0 -154)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/factories/JBossSAMLAuthnResponseFactory.java 217(+0 -217)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/factories/SAMLAssertionFactory.java 197(+0 -197)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/factories/SecurityActions.java 126(+0 -126)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/DestinationInfoHolder.java 56(+0 -56)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/IDPInfoHolder.java 78(+0 -78)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/IssuerInfoHolder.java 80(+0 -80)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/SignatureInfoHolder.java 45(+0 -45)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/SPInfoHolder.java 60(+0 -60)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/DocumentUtil.java 28(+0 -28)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SAMLMetadataUtil.java 101(+0 -101)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SecurityActions.java 161(+0 -161)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SignatureUtil.java 297(+0 -297)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/StatementUtil.java 241(+0 -241)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/StaxWriterUtil.java 166(+0 -166)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/XMLTimeUtil.java 254(+0 -254)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/BaseWriter.java 322(+0 -322)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriter.java 289(+0 -289)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLRequestWriter.java 335(+0 -335)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLResponseWriter.java 264(+0 -264)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/util/CoreConfigUtil.java 208(+0 -208)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/util/EncryptionKeyUtil.java 50(+0 -50)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/util/IDFedLSInputResolver.java 224(+0 -224)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXBUtil.java 280(+0 -280)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXPValidationUtil.java 168(+0 -168)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/util/KeyStoreUtil.java 187(+0 -187)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/util/NamespaceContext.java 96(+0 -96)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/util/ProvidersUtil.java 127(+0 -127)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SchemaManagerUtil.java 106(+0 -106)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SecurityActions.java 225(+0 -225)

saml/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SignatureUtilTransferObject.java 115(+0 -115)

saml/saml-core/src/main/java/org/keycloak/saml/processing/web/util/PostBindingUtil.java 94(+0 -94)

saml/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingSignatureUtil.java 345(+0 -345)

saml/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingUtil.java 219(+0 -219)

saml/saml-core/src/main/java/org/keycloak/saml/processing/web/util/SecurityActions.java 125(+0 -125)

saml/saml-core/src/main/java/org/keycloak/saml/RandomSecret.java 25(+0 -25)

saml/saml-core/src/main/java/org/keycloak/saml/SAML2AuthnRequestBuilder.java 99(+0 -99)

saml/saml-core/src/main/java/org/keycloak/saml/SAML2ErrorResponseBuilder.java 72(+0 -72)

saml/saml-core/src/main/java/org/keycloak/saml/SAML2LoginResponseBuilder.java 195(+0 -195)

saml/saml-core/src/main/java/org/keycloak/saml/SAML2LogoutRequestBuilder.java 87(+0 -87)

saml/saml-core/src/main/java/org/keycloak/saml/SAML2LogoutResponseBuilder.java 75(+0 -75)

saml/saml-core/src/main/java/org/keycloak/saml/SAML2NameIDPolicyBuilder.java 44(+0 -44)

saml/saml-core/src/main/java/org/keycloak/saml/SAMLRequestParser.java 80(+0 -80)

saml/saml-core/src/main/java/org/keycloak/saml/SignatureAlgorithm.java 69(+0 -69)

saml/saml-core/src/main/java/org/keycloak/saml/SPMetadataDescriptor.java 35(+0 -35)

Details

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index ee11349..a7cf76d 100755
--- a/pom.xml
+++ b/pom.xml
@@ -140,7 +140,7 @@
         <module>core</module>
         <module>dependencies</module>
         <module>server-spi</module>
-        <module>saml</module>
+        <module>saml-core</module>
         <module>proxy</module>
         <module>federation</module>
         <module>services</module>
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/IDPListType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/IDPListType.java
new file mode 100755
index 0000000..fe1dbb8
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/IDPListType.java
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for IDPListType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="IDPListType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}IDPEntry" maxOccurs="unbounded"/>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}GetComplete" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class IDPListType {
+
+    protected List<IDPEntryType> idpEntry = new ArrayList<IDPEntryType>();
+    protected URI getComplete;
+
+    /**
+     * Add an idp entry
+     *
+     * @param entry
+     */
+    public void addIDPEntry(IDPEntryType entry) {
+        this.idpEntry.add(entry);
+    }
+
+    /**
+     * Remove an idp entry
+     *
+     * @param entry
+     */
+    public void removeIDPEntry(IDPEntryType entry) {
+        this.idpEntry.remove(entry);
+    }
+
+    /**
+     * Gets the value of the idpEntry property.
+     */
+    public List<IDPEntryType> getIDPEntry() {
+        return Collections.unmodifiableList(this.idpEntry);
+    }
+
+    /**
+     * Gets the value of the getComplete property.
+     *
+     * @return possible object is {@link String }
+     */
+    public URI getGetComplete() {
+        return getComplete;
+    }
+
+    /**
+     * Sets the value of the getComplete property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setGetComplete(URI value) {
+        this.getComplete = value;
+    }
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/LogoutRequestType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/LogoutRequestType.java
new file mode 100755
index 0000000..6db55a1
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/LogoutRequestType.java
@@ -0,0 +1,188 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import org.keycloak.dom.saml.v2.assertion.BaseIDAbstractType;
+import org.keycloak.dom.saml.v2.assertion.EncryptedElementType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for LogoutRequestType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="LogoutRequestType">
+ *   &lt;complexContent>
+ *     &lt;extension base="{urn:oasis:names:tc:SAML:2.0:protocol}RequestAbstractType">
+ *       &lt;sequence>
+ *         &lt;choice>
+ *           &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}BaseID"/>
+ *           &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}NameID"/>
+ *           &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}EncryptedID"/>
+ *         &lt;/choice>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}SessionIndex" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Reason" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="NotOnOrAfter" type="{http://www.w3.org/2001/XMLSchema}dateTime" />
+ *     &lt;/extension>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class LogoutRequestType extends RequestAbstractType {
+
+    protected BaseIDAbstractType baseID;
+
+    protected NameIDType nameID;
+
+    protected EncryptedElementType encryptedID;
+
+    protected List<String> sessionIndex = new ArrayList<String>();
+
+    protected String reason;
+
+    protected XMLGregorianCalendar notOnOrAfter;
+
+    public LogoutRequestType(String id, XMLGregorianCalendar instant) {
+        super(id, instant);
+    }
+
+    /**
+     * Gets the value of the baseID property.
+     *
+     * @return possible object is {@link BaseIDAbstractType }
+     */
+    public BaseIDAbstractType getBaseID() {
+        return baseID;
+    }
+
+    /**
+     * Sets the value of the baseID property.
+     *
+     * @param value allowed object is {@link BaseIDAbstractType }
+     */
+    public void setBaseID(BaseIDAbstractType value) {
+        this.baseID = value;
+    }
+
+    /**
+     * Gets the value of the nameID property.
+     *
+     * @return possible object is {@link NameIDType }
+     */
+    public NameIDType getNameID() {
+        return nameID;
+    }
+
+    /**
+     * Sets the value of the nameID property.
+     *
+     * @param value allowed object is {@link NameIDType }
+     */
+    public void setNameID(NameIDType value) {
+        this.nameID = value;
+    }
+
+    /**
+     * Gets the value of the encryptedID property.
+     *
+     * @return possible object is {@link EncryptedElementType }
+     */
+    public EncryptedElementType getEncryptedID() {
+        return encryptedID;
+    }
+
+    /**
+     * Sets the value of the encryptedID property.
+     *
+     * @param value allowed object is {@link EncryptedElementType }
+     */
+    public void setEncryptedID(EncryptedElementType value) {
+        this.encryptedID = value;
+    }
+
+    /**
+     * Add session index
+     *
+     * @param index
+     */
+    public void addSessionIndex(String index) {
+        this.sessionIndex.add(index);
+    }
+
+    /**
+     * Remove session index
+     *
+     * @param index
+     */
+    public void removeSessionIndex(String index) {
+        this.sessionIndex.remove(index);
+    }
+
+    /**
+     * Gets the value of the sessionIndex property.
+     */
+    public List<String> getSessionIndex() {
+        return Collections.unmodifiableList(this.sessionIndex);
+    }
+
+    /**
+     * Gets the value of the reason property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getReason() {
+        return reason;
+    }
+
+    /**
+     * Sets the value of the reason property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setReason(String value) {
+        this.reason = value;
+    }
+
+    /**
+     * Gets the value of the notOnOrAfter property.
+     *
+     * @return possible object is {@link XMLGregorianCalendar }
+     */
+    public XMLGregorianCalendar getNotOnOrAfter() {
+        return notOnOrAfter;
+    }
+
+    /**
+     * Sets the value of the notOnOrAfter property.
+     *
+     * @param value allowed object is {@link XMLGregorianCalendar }
+     */
+    public void setNotOnOrAfter(XMLGregorianCalendar value) {
+        this.notOnOrAfter = value;
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/ManageNameIDRequestType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/ManageNameIDRequestType.java
new file mode 100755
index 0000000..89952bb
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/ManageNameIDRequestType.java
@@ -0,0 +1,158 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import org.keycloak.dom.saml.v2.assertion.EncryptedElementType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+
+/**
+ * <p>
+ * Java class for ManageNameIDRequestType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="ManageNameIDRequestType">
+ *   &lt;complexContent>
+ *     &lt;extension base="{urn:oasis:names:tc:SAML:2.0:protocol}RequestAbstractType">
+ *       &lt;sequence>
+ *         &lt;choice>
+ *           &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}NameID"/>
+ *           &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}EncryptedID"/>
+ *         &lt;/choice>
+ *         &lt;choice>
+ *           &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}NewID"/>
+ *           &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}NewEncryptedID"/>
+ *           &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}Terminate"/>
+ *         &lt;/choice>
+ *       &lt;/sequence>
+ *     &lt;/extension>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class ManageNameIDRequestType extends RequestAbstractType {
+
+    protected NameIDType nameID;
+
+    protected EncryptedElementType encryptedID;
+
+    protected String newID;
+
+    protected EncryptedElementType newEncryptedID;
+
+    protected TerminateType terminate;
+
+    public ManageNameIDRequestType(String id, XMLGregorianCalendar instant) {
+        super(id, instant);
+    }
+
+    /**
+     * Gets the value of the nameID property.
+     *
+     * @return possible object is {@link NameIDType }
+     */
+    public NameIDType getNameID() {
+        return nameID;
+    }
+
+    /**
+     * Sets the value of the nameID property.
+     *
+     * @param value allowed object is {@link NameIDType }
+     */
+    public void setNameID(NameIDType value) {
+        this.nameID = value;
+    }
+
+    /**
+     * Gets the value of the encryptedID property.
+     *
+     * @return possible object is {@link EncryptedElementType }
+     */
+    public EncryptedElementType getEncryptedID() {
+        return encryptedID;
+    }
+
+    /**
+     * Sets the value of the encryptedID property.
+     *
+     * @param value allowed object is {@link EncryptedElementType }
+     */
+    public void setEncryptedID(EncryptedElementType value) {
+        this.encryptedID = value;
+    }
+
+    /**
+     * Gets the value of the newID property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getNewID() {
+        return newID;
+    }
+
+    /**
+     * Sets the value of the newID property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setNewID(String value) {
+        this.newID = value;
+    }
+
+    /**
+     * Gets the value of the newEncryptedID property.
+     *
+     * @return possible object is {@link EncryptedElementType }
+     */
+    public EncryptedElementType getNewEncryptedID() {
+        return newEncryptedID;
+    }
+
+    /**
+     * Sets the value of the newEncryptedID property.
+     *
+     * @param value allowed object is {@link EncryptedElementType }
+     */
+    public void setNewEncryptedID(EncryptedElementType value) {
+        this.newEncryptedID = value;
+    }
+
+    /**
+     * Gets the value of the terminate property.
+     *
+     * @return possible object is {@link TerminateType }
+     */
+    public TerminateType getTerminate() {
+        return terminate;
+    }
+
+    /**
+     * Sets the value of the terminate property.
+     *
+     * @param value allowed object is {@link TerminateType }
+     */
+    public void setTerminate(TerminateType value) {
+        this.terminate = value;
+    }
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/NameIDMappingRequestType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/NameIDMappingRequestType.java
new file mode 100755
index 0000000..bd5fe43
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/NameIDMappingRequestType.java
@@ -0,0 +1,135 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import org.keycloak.dom.saml.v2.assertion.BaseIDAbstractType;
+import org.keycloak.dom.saml.v2.assertion.EncryptedElementType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+
+/**
+ * <p>
+ * Java class for NameIDMappingRequestType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="NameIDMappingRequestType">
+ *   &lt;complexContent>
+ *     &lt;extension base="{urn:oasis:names:tc:SAML:2.0:protocol}RequestAbstractType">
+ *       &lt;sequence>
+ *         &lt;choice>
+ *           &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}BaseID"/>
+ *           &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}NameID"/>
+ *           &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}EncryptedID"/>
+ *         &lt;/choice>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}NameIDPolicy"/>
+ *       &lt;/sequence>
+ *     &lt;/extension>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class NameIDMappingRequestType extends RequestAbstractType {
+
+    protected BaseIDAbstractType baseID;
+
+    protected NameIDType nameID;
+
+    protected EncryptedElementType encryptedID;
+
+    protected NameIDPolicyType nameIDPolicy;
+
+    public NameIDMappingRequestType(String id, XMLGregorianCalendar instant) {
+        super(id, instant);
+    }
+
+    /**
+     * Gets the value of the baseID property.
+     *
+     * @return possible object is {@link BaseIDAbstractType }
+     */
+    public BaseIDAbstractType getBaseID() {
+        return baseID;
+    }
+
+    /**
+     * Sets the value of the baseID property.
+     *
+     * @param value allowed object is {@link BaseIDAbstractType }
+     */
+    public void setBaseID(BaseIDAbstractType value) {
+        this.baseID = value;
+    }
+
+    /**
+     * Gets the value of the nameID property.
+     *
+     * @return possible object is {@link NameIDType }
+     */
+    public NameIDType getNameID() {
+        return nameID;
+    }
+
+    /**
+     * Sets the value of the nameID property.
+     *
+     * @param value allowed object is {@link NameIDType }
+     */
+    public void setNameID(NameIDType value) {
+        this.nameID = value;
+    }
+
+    /**
+     * Gets the value of the encryptedID property.
+     *
+     * @return possible object is {@link EncryptedElementType }
+     */
+    public EncryptedElementType getEncryptedID() {
+        return encryptedID;
+    }
+
+    /**
+     * Sets the value of the encryptedID property.
+     *
+     * @param value allowed object is {@link EncryptedElementType }
+     */
+    public void setEncryptedID(EncryptedElementType value) {
+        this.encryptedID = value;
+    }
+
+    /**
+     * Gets the value of the nameIDPolicy property.
+     *
+     * @return possible object is {@link NameIDPolicyType }
+     */
+    public NameIDPolicyType getNameIDPolicy() {
+        return nameIDPolicy;
+    }
+
+    /**
+     * Sets the value of the nameIDPolicy property.
+     *
+     * @param value allowed object is {@link NameIDPolicyType }
+     */
+    public void setNameIDPolicy(NameIDPolicyType value) {
+        this.nameIDPolicy = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/NameIDMappingResponseType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/NameIDMappingResponseType.java
new file mode 100755
index 0000000..dedc8ff
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/NameIDMappingResponseType.java
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import org.keycloak.dom.saml.v2.assertion.EncryptedElementType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+
+/**
+ * <p>
+ * Java class for NameIDMappingResponseType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="NameIDMappingResponseType">
+ *   &lt;complexContent>
+ *     &lt;extension base="{urn:oasis:names:tc:SAML:2.0:protocol}StatusResponseType">
+ *       &lt;choice>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}NameID"/>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}EncryptedID"/>
+ *       &lt;/choice>
+ *     &lt;/extension>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class NameIDMappingResponseType extends StatusResponseType {
+
+    protected NameIDType nameID;
+
+    protected EncryptedElementType encryptedID;
+
+    public NameIDMappingResponseType(String id, XMLGregorianCalendar issueInstant) {
+        super(id, issueInstant);
+    }
+
+    /**
+     * Gets the value of the nameID property.
+     *
+     * @return possible object is {@link NameIDType }
+     */
+    public NameIDType getNameID() {
+        return nameID;
+    }
+
+    /**
+     * Sets the value of the nameID property.
+     *
+     * @param value allowed object is {@link NameIDType }
+     */
+    public void setNameID(NameIDType value) {
+        this.nameID = value;
+    }
+
+    /**
+     * Gets the value of the encryptedID property.
+     *
+     * @return possible object is {@link EncryptedElementType }
+     */
+    public EncryptedElementType getEncryptedID() {
+        return encryptedID;
+    }
+
+    /**
+     * Sets the value of the encryptedID property.
+     *
+     * @param value allowed object is {@link EncryptedElementType }
+     */
+    public void setEncryptedID(EncryptedElementType value) {
+        this.encryptedID = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/NameIDPolicyType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/NameIDPolicyType.java
new file mode 100755
index 0000000..6383108
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/NameIDPolicyType.java
@@ -0,0 +1,100 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import java.net.URI;
+
+/**
+ * <p>
+ * Java class for NameIDPolicyType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="NameIDPolicyType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;attribute name="Format" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *       &lt;attribute name="SPNameQualifier" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="AllowCreate" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class NameIDPolicyType {
+
+    protected URI format;
+    protected String spNameQualifier;
+    protected Boolean allowCreate = Boolean.FALSE;
+
+    /**
+     * Gets the value of the format property.
+     *
+     * @return possible object is {@link String }
+     */
+    public URI getFormat() {
+        return format;
+    }
+
+    /**
+     * Sets the value of the format property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setFormat(URI value) {
+        this.format = value;
+    }
+
+    /**
+     * Gets the value of the spNameQualifier property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getSPNameQualifier() {
+        return spNameQualifier;
+    }
+
+    /**
+     * Sets the value of the spNameQualifier property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setSPNameQualifier(String value) {
+        this.spNameQualifier = value;
+    }
+
+    /**
+     * Gets the value of the allowCreate property.
+     *
+     * @return possible object is {@link Boolean }
+     */
+    public Boolean isAllowCreate() {
+        return allowCreate;
+    }
+
+    /**
+     * Sets the value of the allowCreate property.
+     *
+     * @param value allowed object is {@link Boolean }
+     */
+    public void setAllowCreate(Boolean value) {
+        this.allowCreate = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/RequestAbstractType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/RequestAbstractType.java
new file mode 100755
index 0000000..c670169
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/RequestAbstractType.java
@@ -0,0 +1,149 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import org.keycloak.dom.saml.common.CommonRequestAbstractType;
+import org.keycloak.dom.saml.v2.SAML2Object;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import java.net.URI;
+
+/**
+ * <p>
+ * Java class for RequestAbstractType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="RequestAbstractType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}Issuer" minOccurs="0"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}Signature" minOccurs="0"/>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}Extensions" minOccurs="0"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="ID" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *       &lt;attribute name="Version" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="IssueInstant" use="required" type="{http://www.w3.org/2001/XMLSchema}dateTime" />
+ *       &lt;attribute name="Destination" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *       &lt;attribute name="Consent" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public abstract class RequestAbstractType extends CommonRequestAbstractType implements SAML2Object {
+
+    protected NameIDType issuer;
+
+    protected ExtensionsType extensions;
+
+    protected String version = "2.0";
+
+    protected URI destination;
+
+    protected String consent;
+
+    public RequestAbstractType(String id, XMLGregorianCalendar instant) {
+        super(id, instant);
+    }
+
+    /**
+     * Gets the value of the issuer property.
+     *
+     * @return possible object is {@link NameIDType }
+     */
+    public NameIDType getIssuer() {
+        return issuer;
+    }
+
+    /**
+     * Sets the value of the issuer property.
+     *
+     * @param value allowed object is {@link NameIDType }
+     */
+    public void setIssuer(NameIDType value) {
+        this.issuer = value;
+    }
+
+    /**
+     * Gets the value of the extensions property.
+     *
+     * @return possible object is {@link ExtensionsType }
+     */
+    public ExtensionsType getExtensions() {
+        return extensions;
+    }
+
+    /**
+     * Sets the value of the extensions property.
+     *
+     * @param value allowed object is {@link ExtensionsType }
+     */
+    public void setExtensions(ExtensionsType value) {
+        this.extensions = value;
+    }
+
+    /**
+     * Gets the value of the version property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getVersion() {
+        return version;
+    }
+
+    /**
+     * Gets the value of the destination property.
+     *
+     * @return possible object is {@link String }
+     */
+    public URI getDestination() {
+        return destination;
+    }
+
+    /**
+     * Sets the value of the destination property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setDestination(URI value) {
+        this.destination = value;
+    }
+
+    /**
+     * Gets the value of the consent property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getConsent() {
+        return consent;
+    }
+
+    /**
+     * Sets the value of the consent property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setConsent(String value) {
+        this.consent = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/RequestedAuthnContextType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/RequestedAuthnContextType.java
new file mode 100755
index 0000000..0aea25e
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/RequestedAuthnContextType.java
@@ -0,0 +1,135 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for RequestedAuthnContextType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="RequestedAuthnContextType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;choice>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}AuthnContextClassRef" maxOccurs="unbounded"/>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}AuthnContextDeclRef" maxOccurs="unbounded"/>
+ *       &lt;/choice>
+ *       &lt;attribute name="Comparison" type="{urn:oasis:names:tc:SAML:2.0:protocol}AuthnContextComparisonType" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class RequestedAuthnContextType {
+
+    protected List<String> authnContextClassRef = new ArrayList<String>();
+    protected List<String> authnContextDeclRef = new ArrayList<String>();
+    protected AuthnContextComparisonType comparison;
+
+    /**
+     * Add an authn Context class ref
+     *
+     * @param str
+     */
+    public void addAuthnContextClassRef(String str) {
+        this.authnContextClassRef.add(str);
+    }
+
+    /**
+     * Add authn context decl ref
+     *
+     * @param str
+     */
+    public void addAuthnContextDeclRef(String str) {
+        this.authnContextDeclRef.add(str);
+    }
+
+    /**
+     * Remove an authn Context class ref
+     *
+     * @param str
+     */
+    public void removeAuthnContextClassRef(String str) {
+        this.authnContextClassRef.remove(str);
+    }
+
+    /**
+     * remove authn context decl ref
+     *
+     * @param str
+     */
+    public void removeAuthnContextDeclRef(String str) {
+        this.authnContextDeclRef.remove(str);
+    }
+
+    /**
+     * Gets the value of the authnContextClassRef property.
+     */
+    public List<String> getAuthnContextClassRef() {
+        return Collections.unmodifiableList(this.authnContextClassRef);
+    }
+
+    /**
+     * Gets the value of the authnContextDeclRef property.
+     *
+     * <p>
+     * This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make to
+     * the
+     * returned list will be present inside the JAXB object. This is why there is not a <CODE>set</CODE> method for the
+     * authnContextDeclRef property.
+     *
+     * <p>
+     * For example, to add a new item, do as follows:
+     *
+     * <pre>
+     * getAuthnContextDeclRef().add(newItem);
+     * </pre>
+     *
+     *
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link String }
+     */
+    public List<String> getAuthnContextDeclRef() {
+        return Collections.unmodifiableList(this.authnContextDeclRef);
+    }
+
+    /**
+     * Gets the value of the comparison property.
+     *
+     * @return possible object is {@link AuthnContextComparisonType }
+     */
+    public AuthnContextComparisonType getComparison() {
+        return comparison;
+    }
+
+    /**
+     * Sets the value of the comparison property.
+     *
+     * @param value allowed object is {@link AuthnContextComparisonType }
+     */
+    public void setComparison(AuthnContextComparisonType value) {
+        this.comparison = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/ResponseType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/ResponseType.java
new file mode 100755
index 0000000..fec0f13
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/ResponseType.java
@@ -0,0 +1,135 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
+import org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for ResponseType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="ResponseType">
+ *   &lt;complexContent>
+ *     &lt;extension base="{urn:oasis:names:tc:SAML:2.0:protocol}StatusResponseType">
+ *       &lt;choice maxOccurs="unbounded" minOccurs="0">
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}Assertion"/>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}EncryptedAssertion"/>
+ *       &lt;/choice>
+ *     &lt;/extension>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class ResponseType extends StatusResponseType {
+
+    protected List<RTChoiceType> assertions = new ArrayList<ResponseType.RTChoiceType>();
+
+    public ResponseType(String id, XMLGregorianCalendar issueInstant) {
+        super(id, issueInstant);
+    }
+
+    public ResponseType(StatusResponseType srt) {
+        super(srt);
+    }
+
+    /**
+     * Add an assertion
+     *
+     * @param choice
+     */
+    public void addAssertion(RTChoiceType choice) {
+        assertions.add(choice);
+    }
+
+    /**
+     * Remove an assertion
+     *
+     * @param choice
+     */
+    public void removeAssertion(RTChoiceType choice) {
+        assertions.remove(choice);
+    }
+
+    /**
+     * Replace the first assertion with the passed assertion
+     *
+     * @param id id of the old assertion
+     * @param newAssertion
+     */
+    public void replaceAssertion(String id, RTChoiceType newAssertion) {
+        int index = 0;
+        if (id != null && !id.isEmpty()) {
+            for (RTChoiceType assertion : assertions) {
+                if (assertion.getID().equals(id)) {
+                    break;
+                }
+                index++;
+            }
+        }
+        assertions.remove(index);
+        assertions.add(index, newAssertion);
+    }
+
+    /**
+     * Gets a read only list of assertions
+     */
+    public List<RTChoiceType> getAssertions() {
+        return Collections.unmodifiableList(assertions);
+    }
+
+    public static class RTChoiceType {
+
+        private AssertionType assertion;
+
+        private EncryptedAssertionType encryptedAssertion;
+
+        private String id;
+
+        public RTChoiceType(AssertionType assertion) {
+            this.assertion = assertion;
+            this.id = assertion.getID();
+        }
+
+        public RTChoiceType(EncryptedAssertionType encryptedAssertion) {
+            this.encryptedAssertion = encryptedAssertion;
+
+        }
+
+        public AssertionType getAssertion() {
+            return assertion;
+        }
+
+        public EncryptedAssertionType getEncryptedAssertion() {
+            return encryptedAssertion;
+        }
+
+        public String getID() {
+            return id;
+        }
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/ScopingType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/ScopingType.java
new file mode 100755
index 0000000..bcd8060
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/ScopingType.java
@@ -0,0 +1,125 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import java.math.BigInteger;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for ScopingType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="ScopingType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}IDPList" minOccurs="0"/>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}RequesterID" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="ProxyCount" type="{http://www.w3.org/2001/XMLSchema}nonNegativeInteger" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class ScopingType {
+
+    protected IDPListType idpList;
+    protected List<URI> requesterID = new ArrayList<URI>();
+
+    protected BigInteger proxyCount;
+
+    /**
+     * Gets the value of the idpList property.
+     *
+     * @return possible object is {@link IDPListType }
+     */
+    public IDPListType getIDPList() {
+        return idpList;
+    }
+
+    /**
+     * Sets the value of the idpList property.
+     *
+     * @param value allowed object is {@link IDPListType }
+     */
+    public void setIDPList(IDPListType value) {
+        this.idpList = value;
+    }
+
+    /**
+     * Gets the value of the requesterID property.
+     * <p>
+     * For example, to add a new item, do as follows:
+     *
+     * <pre>
+     * getRequesterID().add(newItem);
+     * </pre>
+     *
+     *
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link String }
+     */
+    public List<URI> getRequesterID() {
+        return Collections.unmodifiableList(this.requesterID);
+    }
+
+    /**
+     * Add requester id
+     *
+     * @param uri
+     */
+    public void addRequesterID(URI uri) {
+        this.requesterID.add(uri);
+    }
+
+    /**
+     * Remove requester id
+     *
+     * @param uri
+     */
+    public void removeRequesterID(URI uri) {
+        this.requesterID.remove(uri);
+    }
+
+    /**
+     * Gets the value of the proxyCount property.
+     *
+     * @return possible object is {@link BigInteger }
+     */
+    public BigInteger getProxyCount() {
+        return proxyCount;
+    }
+
+    /**
+     * Sets the value of the proxyCount property.
+     *
+     * @param value allowed object is {@link BigInteger }
+     */
+    public void setProxyCount(BigInteger value) {
+        this.proxyCount = value;
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusCodeType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusCodeType.java
new file mode 100755
index 0000000..826928a
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusCodeType.java
@@ -0,0 +1,89 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import java.io.Serializable;
+import java.net.URI;
+
+/**
+ * <p>
+ * Java class for StatusCodeType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="StatusCodeType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}StatusCode" minOccurs="0"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Value" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class StatusCodeType implements Serializable {
+
+    protected StatusCodeType statusCode;
+    protected URI value;
+
+    /**
+     * Gets the value of the statusCode property.
+     *
+     * @return possible object is {@link StatusCodeType }
+     */
+    public StatusCodeType getStatusCode() {
+        return statusCode;
+    }
+
+    /**
+     * Sets the value of the statusCode property.
+     *
+     * @param value allowed object is {@link StatusCodeType }
+     */
+    public void setStatusCode(StatusCodeType value) {
+        this.statusCode = value;
+    }
+
+    /**
+     * Gets the value of the value property.
+     *
+     * @return possible object is {@link String }
+     */
+    public URI getValue() {
+        return value;
+    }
+
+    /**
+     * Sets the value of the value property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setValue(URI value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return "StatusCodeType [value=" + value + ", statusCode=" + statusCode + "]";
+    }
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusResponseType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusResponseType.java
new file mode 100755
index 0000000..12235b3
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusResponseType.java
@@ -0,0 +1,185 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import org.keycloak.dom.saml.common.CommonResponseType;
+import org.keycloak.dom.saml.v2.SAML2Object;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+
+/**
+ * <p>
+ * Java class for StatusResponseType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="StatusResponseType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}Issuer" minOccurs="0"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}Signature" minOccurs="0"/>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}Extensions" minOccurs="0"/>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}Status"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="ID" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *       &lt;attribute name="InResponseTo" type="{http://www.w3.org/2001/XMLSchema}NCName" />
+ *       &lt;attribute name="Version" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="IssueInstant" use="required" type="{http://www.w3.org/2001/XMLSchema}dateTime" />
+ *       &lt;attribute name="Destination" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *       &lt;attribute name="Consent" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class StatusResponseType extends CommonResponseType implements SAML2Object {
+
+    protected NameIDType issuer;
+
+    protected ExtensionsType extensions;
+
+    protected StatusType status;
+
+    protected String id;
+
+    protected String version = "2.0";
+
+    protected XMLGregorianCalendar issueInstant;
+
+    protected String destination;
+
+    protected String consent;
+
+    public StatusResponseType(String id, XMLGregorianCalendar issueInstant) {
+        super(id, issueInstant);
+    }
+
+    public StatusResponseType(StatusResponseType srt) {
+        this(srt.getID(), srt.getIssueInstant());
+        this.issuer = srt.getIssuer();
+        this.signature = srt.getSignature();
+        this.extensions = srt.getExtensions();
+        this.status = srt.getStatus();
+        this.inResponseTo = srt.getInResponseTo();
+        this.destination = srt.getDestination();
+        this.consent = srt.getConsent();
+    }
+
+    /**
+     * Gets the value of the issuer property.
+     *
+     * @return possible object is {@link NameIDType }
+     */
+    public NameIDType getIssuer() {
+        return issuer;
+    }
+
+    /**
+     * Sets the value of the issuer property.
+     *
+     * @param value allowed object is {@link NameIDType }
+     */
+    public void setIssuer(NameIDType value) {
+        this.issuer = value;
+    }
+
+    /**
+     * Gets the value of the extensions property.
+     *
+     * @return possible object is {@link ExtensionsType }
+     */
+    public ExtensionsType getExtensions() {
+        return extensions;
+    }
+
+    /**
+     * Sets the value of the extensions property.
+     *
+     * @param value allowed object is {@link ExtensionsType }
+     */
+    public void setExtensions(ExtensionsType value) {
+        this.extensions = value;
+    }
+
+    /**
+     * Gets the value of the status property.
+     *
+     * @return possible object is {@link StatusType }
+     */
+    public StatusType getStatus() {
+        return status;
+    }
+
+    /**
+     * Sets the value of the status property.
+     *
+     * @param value allowed object is {@link StatusType }
+     */
+    public void setStatus(StatusType value) {
+        this.status = value;
+    }
+
+    /**
+     * Gets the value of the version property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getVersion() {
+        return version;
+    }
+
+    /**
+     * Gets the value of the destination property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getDestination() {
+        return destination;
+    }
+
+    /**
+     * Sets the value of the destination property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setDestination(String value) {
+        this.destination = value;
+    }
+
+    /**
+     * Gets the value of the consent property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getConsent() {
+        return consent;
+    }
+
+    /**
+     * Sets the value of the consent property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setConsent(String value) {
+        this.consent = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusType.java
new file mode 100755
index 0000000..ec92dd4
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusType.java
@@ -0,0 +1,108 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * Java class for StatusType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="StatusType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}StatusCode"/>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}StatusMessage" minOccurs="0"/>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:protocol}StatusDetail" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class StatusType implements Serializable {
+
+    protected String statusMessage;
+    protected StatusCodeType statusCode;
+    protected StatusDetailType statusDetail;
+
+    /**
+     * Gets the value of the statusCode property.
+     *
+     * @return possible object is {@link StatusCodeType }
+     */
+    public StatusCodeType getStatusCode() {
+        return statusCode;
+    }
+
+    /**
+     * Sets the value of the statusCode property.
+     *
+     * @param value allowed object is {@link StatusCodeType }
+     */
+    public void setStatusCode(StatusCodeType value) {
+        this.statusCode = value;
+    }
+
+    /**
+     * Gets the value of the statusMessage property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getStatusMessage() {
+        return statusMessage;
+    }
+
+    /**
+     * Sets the value of the statusMessage property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setStatusMessage(String value) {
+        this.statusMessage = value;
+    }
+
+    /**
+     * Gets the value of the statusDetail property.
+     *
+     * @return possible object is {@link StatusDetailType }
+     */
+    public StatusDetailType getStatusDetail() {
+        return statusDetail;
+    }
+
+    /**
+     * Sets the value of the statusDetail property.
+     *
+     * @param value allowed object is {@link StatusDetailType }
+     */
+    public void setStatusDetail(StatusDetailType value) {
+        this.statusDetail = value;
+    }
+
+    @Override
+    public String toString() {
+        return "StatusType [statusCode=" + statusCode + ", statusMessage=" + statusMessage + ", statusDetail=" + statusDetail + "]";
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/SubjectQueryAbstractType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/SubjectQueryAbstractType.java
new file mode 100755
index 0000000..857e3e7
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/SubjectQueryAbstractType.java
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+import org.keycloak.dom.saml.v2.assertion.SubjectType;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+
+/**
+ * <p>
+ * Java class for SubjectQueryAbstractType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="SubjectQueryAbstractType">
+ *   &lt;complexContent>
+ *     &lt;extension base="{urn:oasis:names:tc:SAML:2.0:protocol}RequestAbstractType">
+ *       &lt;sequence>
+ *         &lt;element ref="{urn:oasis:names:tc:SAML:2.0:assertion}Subject"/>
+ *       &lt;/sequence>
+ *     &lt;/extension>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public abstract class SubjectQueryAbstractType extends RequestAbstractType {
+
+    protected SubjectType subject;
+
+    public SubjectQueryAbstractType(String id, XMLGregorianCalendar instant) {
+        super(id, instant);
+    }
+
+    public void setSubject(SubjectType subject) {
+        this.subject = subject;
+    }
+
+    /**
+     * Gets the value of the subject property.
+     *
+     * @return possible object is {@link SubjectType }
+     */
+    public SubjectType getSubject() {
+        return subject;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/TerminateType.java b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/TerminateType.java
new file mode 100755
index 0000000..8a3890e
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/TerminateType.java
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.saml.v2.protocol;
+
+/**
+ * <p>
+ * Java class for TerminateType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="TerminateType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class TerminateType {
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/CanonicalizationMethodType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/CanonicalizationMethodType.java
new file mode 100755
index 0000000..6529ae0
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/CanonicalizationMethodType.java
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.net.URI;
+
+/**
+ * <p>
+ * Java class for CanonicalizationMethodType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="CanonicalizationMethodType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;any/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Algorithm" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class CanonicalizationMethodType {
+
+    protected URI algorithm;
+    private Object content;
+
+    public CanonicalizationMethodType(URI algorithm) {
+        this.algorithm = algorithm;
+    }
+
+    public void setContent(Object content) {
+        this.content = content;
+    }
+
+    public Object getContent() {
+        return this.content;
+    }
+
+    /**
+     * Gets the value of the algorithm property.
+     *
+     * @return possible object is {@link String }
+     */
+    public URI getAlgorithm() {
+        return algorithm;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/DigestMethodType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/DigestMethodType.java
new file mode 100755
index 0000000..1e8cb42
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/DigestMethodType.java
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.net.URI;
+
+/**
+ * <p>
+ * Java class for DigestMethodType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="DigestMethodType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;any/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Algorithm" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class DigestMethodType {
+
+    protected URI algorithm;
+    private Object content;
+
+    public DigestMethodType(URI algorithm) {
+        this.algorithm = algorithm;
+    }
+
+    public void setContent(Object content) {
+        this.content = content;
+    }
+
+    public Object getContent() {
+        return this.content;
+    }
+
+    /**
+     * Gets the value of the algorithm property.
+     *
+     * @return possible object is {@link URI }
+     */
+    public URI getAlgorithm() {
+        return algorithm;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/KeyInfoType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/KeyInfoType.java
new file mode 100755
index 0000000..d764fef
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/KeyInfoType.java
@@ -0,0 +1,86 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for KeyInfoType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="KeyInfoType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;choice maxOccurs="unbounded">
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}KeyName"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}KeyValue"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}RetrievalMethod"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}X509Data"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}PGPData"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}SPKIData"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}MgmtData"/>
+ *         &lt;any/>
+ *       &lt;/choice>
+ *       &lt;attribute name="Id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class KeyInfoType {
+
+    protected String id;
+
+    protected List<Object> contentList = new ArrayList<Object>();
+
+    public void addContent(Object content) {
+        this.contentList.add(content);
+    }
+
+    public void removeContent(Object content) {
+        this.contentList.remove(content);
+    }
+
+    public List<Object> getContent() {
+        return Collections.unmodifiableList(contentList);
+    }
+
+    /**
+     * Gets the value of the id property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/KeyValueType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/KeyValueType.java
new file mode 100755
index 0000000..fdef5a5
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/KeyValueType.java
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+
+/**
+ * <p>
+ * Java class for KeyValueType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="KeyValueType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;choice>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}DSAKeyValue"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}RSAKeyValue"/>
+ *         &lt;any/>
+ *       &lt;/choice>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public interface KeyValueType {
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/ManifestType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/ManifestType.java
new file mode 100755
index 0000000..f7040b9
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/ManifestType.java
@@ -0,0 +1,84 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for ManifestType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="ManifestType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}Reference" maxOccurs="unbounded"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class ManifestType {
+
+    protected List<ReferenceType> reference = new ArrayList<ReferenceType>();
+    protected String id;
+
+    public void addReference(ReferenceType ref) {
+        this.reference.add(ref);
+    }
+
+    public void removeReference(ReferenceType ref) {
+        this.reference.remove(ref);
+    }
+
+    /**
+     * Gets the value of the reference property.
+     *
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link ReferenceType }
+     */
+    public List<ReferenceType> getReference() {
+        return Collections.unmodifiableList(this.reference);
+    }
+
+    /**
+     * Gets the value of the id property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/ObjectType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/ObjectType.java
new file mode 100755
index 0000000..e60ffd0
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/ObjectType.java
@@ -0,0 +1,123 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for ObjectType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="ObjectType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence maxOccurs="unbounded" minOccurs="0">
+ *         &lt;any/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *       &lt;attribute name="MimeType" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="Encoding" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class ObjectType {
+
+    protected List<Object> content = new ArrayList<Object>();
+    protected String id;
+    protected String mimeType;
+    protected String encoding;
+
+    public void add(Object obj) {
+        this.content.add(obj);
+    }
+
+    public void remove(Object obj) {
+        this.content.remove(obj);
+    }
+
+    /**
+     * Gets the value of the content property.
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link org.w3c.dom.Element } {@link Object } {@link String }
+     */
+    public List<Object> getContent() {
+        return Collections.unmodifiableList(this.content);
+    }
+
+    /**
+     * Gets the value of the id property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+    /**
+     * Gets the value of the mimeType property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getMimeType() {
+        return mimeType;
+    }
+
+    /**
+     * Sets the value of the mimeType property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setMimeType(String value) {
+        this.mimeType = value;
+    }
+
+    /**
+     * Gets the value of the encoding property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getEncoding() {
+        return encoding;
+    }
+
+    /**
+     * Sets the value of the encoding property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setEncoding(String value) {
+        this.encoding = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/package-info.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/package-info.java
new file mode 100755
index 0000000..73e4e41
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/PGPDataType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/PGPDataType.java
new file mode 100755
index 0000000..89084aa
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/PGPDataType.java
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for PGPDataType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="PGPDataType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;choice>
+ *         &lt;sequence>
+ *           &lt;element name="PGPKeyID" type="{http://www.w3.org/2001/XMLSchema}base64Binary"/>
+ *           &lt;element name="PGPKeyPacket" type="{http://www.w3.org/2001/XMLSchema}base64Binary" minOccurs="0"/>
+ *           &lt;any/>
+ *         &lt;/sequence>
+ *         &lt;sequence>
+ *           &lt;element name="PGPKeyPacket" type="{http://www.w3.org/2001/XMLSchema}base64Binary"/>
+ *           &lt;any/>
+ *         &lt;/sequence>
+ *       &lt;/choice>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class PGPDataType {
+
+    protected List<Object> content = new ArrayList<Object>();
+
+    public void add(Object obj) {
+        this.content.add(obj);
+    }
+
+    public void remove(Object obj) {
+        this.content.remove(obj);
+    }
+
+    /**
+     * Gets the value of the content property.
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link org.w3c.dom.Element } {@link Object } {@link String }
+     */
+    public List<Object> getContent() {
+        return Collections.unmodifiableList(this.content);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/ReferenceType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/ReferenceType.java
new file mode 100755
index 0000000..ea95b05
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/ReferenceType.java
@@ -0,0 +1,160 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+/**
+ * <p>
+ * Java class for ReferenceType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="ReferenceType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}Transforms" minOccurs="0"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}DigestMethod"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}DigestValue"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *       &lt;attribute name="URI" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *       &lt;attribute name="Type" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class ReferenceType {
+
+    protected TransformsType transforms;
+    protected DigestMethodType digestMethod;
+    protected byte[] digestValue;
+    protected String id;
+    protected String uri;
+    protected String type;
+
+    /**
+     * Gets the value of the transforms property.
+     *
+     * @return possible object is {@link TransformsType }
+     */
+    public TransformsType getTransforms() {
+        return transforms;
+    }
+
+    /**
+     * Sets the value of the transforms property.
+     *
+     * @param value allowed object is {@link TransformsType }
+     */
+    public void setTransforms(TransformsType value) {
+        this.transforms = value;
+    }
+
+    /**
+     * Gets the value of the digestMethod property.
+     *
+     * @return possible object is {@link DigestMethodType }
+     */
+    public DigestMethodType getDigestMethod() {
+        return digestMethod;
+    }
+
+    /**
+     * Sets the value of the digestMethod property.
+     *
+     * @param value allowed object is {@link DigestMethodType }
+     */
+    public void setDigestMethod(DigestMethodType value) {
+        this.digestMethod = value;
+    }
+
+    /**
+     * Gets the value of the digestValue property.
+     *
+     * @return possible object is byte[]
+     */
+    public byte[] getDigestValue() {
+        return digestValue;
+    }
+
+    /**
+     * Sets the value of the digestValue property.
+     *
+     * @param value allowed object is byte[]
+     */
+    public void setDigestValue(byte[] value) {
+        this.digestValue = ((byte[]) value);
+    }
+
+    /**
+     * Gets the value of the id property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+    /**
+     * Gets the value of the uri property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getURI() {
+        return uri;
+    }
+
+    /**
+     * Sets the value of the uri property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setURI(String value) {
+        this.uri = value;
+    }
+
+    /**
+     * Gets the value of the type property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * Sets the value of the type property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setType(String value) {
+        this.type = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/RetrievalMethodType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/RetrievalMethodType.java
new file mode 100755
index 0000000..32c6974
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/RetrievalMethodType.java
@@ -0,0 +1,101 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+/**
+ * <p>
+ * Java class for RetrievalMethodType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="RetrievalMethodType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}Transforms" minOccurs="0"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="URI" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *       &lt;attribute name="Type" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class RetrievalMethodType {
+
+    protected TransformsType transforms;
+    protected String uri;
+    protected String type;
+
+    /**
+     * Gets the value of the transforms property.
+     *
+     * @return possible object is {@link TransformsType }
+     */
+    public TransformsType getTransforms() {
+        return transforms;
+    }
+
+    /**
+     * Sets the value of the transforms property.
+     *
+     * @param value allowed object is {@link TransformsType }
+     */
+    public void setTransforms(TransformsType value) {
+        this.transforms = value;
+    }
+
+    /**
+     * Gets the value of the uri property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getURI() {
+        return uri;
+    }
+
+    /**
+     * Sets the value of the uri property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setURI(String value) {
+        this.uri = value;
+    }
+
+    /**
+     * Gets the value of the type property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * Sets the value of the type property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setType(String value) {
+        this.type = value;
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/RSAKeyValueType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/RSAKeyValueType.java
new file mode 100755
index 0000000..0ded3fd
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/RSAKeyValueType.java
@@ -0,0 +1,164 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import org.keycloak.saml.common.constants.WSTrustConstants;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.util.Base64;
+
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+
+/**
+ * <p>
+ * Java class for RSAKeyValueType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="RSAKeyValueType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="Modulus" type="{http://www.w3.org/2000/09/xmldsig#}CryptoBinary"/>
+ *         &lt;element name="Exponent" type="{http://www.w3.org/2000/09/xmldsig#}CryptoBinary"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class RSAKeyValueType implements KeyValueType {
+
+    protected byte[] modulus;
+    protected byte[] exponent;
+
+    /**
+     * Gets the value of the modulus property.
+     *
+     * @return possible object is byte[]
+     */
+    public byte[] getModulus() {
+        return modulus;
+    }
+
+    /**
+     * Sets the value of the modulus property.
+     *
+     * @param value allowed object is byte[]
+     */
+    public void setModulus(byte[] value) {
+        this.modulus = ((byte[]) value);
+    }
+
+    /**
+     * Gets the value of the exponent property.
+     *
+     * @return possible object is byte[]
+     */
+    public byte[] getExponent() {
+        return exponent;
+    }
+
+    /**
+     * Sets the value of the exponent property.
+     *
+     * @param value allowed object is byte[]
+     */
+    public void setExponent(byte[] value) {
+        this.exponent = ((byte[]) value);
+    }
+
+    /**
+     * Convert to the JDK representation of a RSA Public Key
+     *
+     * @return
+     *
+     * @throws org.keycloak.saml.common.exceptions.ProcessingException
+     */
+    public RSAPublicKey convertToPublicKey() throws ProcessingException {
+        BigInteger bigModulus = new BigInteger(1, massage(Base64.decode(new String(modulus))));
+        BigInteger bigEx = new BigInteger(1, massage(Base64.decode(new String(exponent))));
+
+        try {
+            KeyFactory rsaKeyFactory = KeyFactory.getInstance("rsa");
+            RSAPublicKeySpec kspec = new RSAPublicKeySpec(bigModulus, bigEx);
+            return (RSAPublicKey) rsaKeyFactory.generatePublic(kspec);
+        } catch (Exception e) {
+            throw new ProcessingException(e);
+        }
+    }
+
+    /**
+     * Convert to the JDK representation of a RSA Private Key
+     *
+     * @return
+     *
+     * @throws ProcessingException
+     */
+    public RSAPrivateKey convertToPrivateKey() throws ProcessingException {
+        BigInteger bigModulus = new BigInteger(1, massage(Base64.decode(new String(modulus))));
+        BigInteger bigEx = new BigInteger(1, massage(Base64.decode(new String(exponent))));
+
+        try {
+            KeyFactory rsaKeyFactory = KeyFactory.getInstance("rsa");
+            RSAPrivateKeySpec kspec = new RSAPrivateKeySpec(bigModulus, bigEx);
+            return (RSAPrivateKey) rsaKeyFactory.generatePrivate(kspec);
+        } catch (Exception e) {
+            throw new ProcessingException(e);
+        }
+    }
+
+    public String toString() {
+        String prefix = WSTrustConstants.XMLDSig.DSIG_PREFIX;
+        String colon = ":";
+        String left = "<";
+        String right = ">";
+        String slash = "/";
+
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(left).append(prefix).append(colon).append(WSTrustConstants.XMLDSig.RSA_KEYVALUE).append(right);
+
+        sb.append(left).append(prefix).append(colon).append(WSTrustConstants.XMLDSig.MODULUS).append(right);
+        sb.append(new String(getModulus()));
+        sb.append(left).append(slash).append(prefix).append(colon).append(WSTrustConstants.XMLDSig.MODULUS).append(right);
+
+        sb.append(left).append(prefix).append(colon).append(WSTrustConstants.XMLDSig.EXPONENT).append(right);
+        sb.append(new String(getExponent()));
+        sb.append(left).append(slash).append(prefix).append(colon).append(WSTrustConstants.XMLDSig.EXPONENT).append(right);
+
+        sb.append(left).append(slash).append(prefix).append(colon).append(WSTrustConstants.XMLDSig.RSA_KEYVALUE).append(right);
+        return sb.toString();
+    }
+
+    private byte[] massage(byte[] byteArray) {
+        if (byteArray[0] == 0) {
+            byte[] substring = new byte[byteArray.length - 1];
+            System.arraycopy(byteArray, 1, substring, 0, byteArray.length - 1);
+            return substring;
+        }
+        return byteArray;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignatureMethodType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignatureMethodType.java
new file mode 100755
index 0000000..9f2c4af
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignatureMethodType.java
@@ -0,0 +1,86 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for SignatureMethodType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="SignatureMethodType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="HMACOutputLength" type="{http://www.w3.org/2000/09/xmldsig#}HMACOutputLengthType"
+ * minOccurs="0"/>
+ *         &lt;any/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Algorithm" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class SignatureMethodType {
+
+    protected List<Object> content = new ArrayList<Object>();
+    protected String algorithm;
+
+    public void add(Object obj) {
+        this.content.add(obj);
+    }
+
+    public void remove(Object obj) {
+        this.content.remove(obj);
+    }
+
+    /**
+     * Gets the value of the content property.
+     *
+     * {@link Object } {@link String }
+     */
+    public List<Object> getContent() {
+        return Collections.unmodifiableList(this.content);
+    }
+
+    /**
+     * Gets the value of the algorithm property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    /**
+     * Sets the value of the algorithm property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setAlgorithm(String value) {
+        this.algorithm = value;
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignaturePropertiesType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignaturePropertiesType.java
new file mode 100755
index 0000000..9f38ffc
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignaturePropertiesType.java
@@ -0,0 +1,85 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for SignaturePropertiesType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="SignaturePropertiesType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}SignatureProperty" maxOccurs="unbounded"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class SignaturePropertiesType {
+
+    protected List<SignaturePropertyType> signatureProperty = new ArrayList<SignaturePropertyType>();
+    protected String id;
+
+    public void addSignatureProperty(SignaturePropertyType sig) {
+        this.signatureProperty.add(sig);
+    }
+
+    public void removeSignatureProperty(SignaturePropertyType sig) {
+        this.signatureProperty.remove(sig);
+    }
+
+    /**
+     * Gets the value of the signatureProperty property.
+     *
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link SignaturePropertyType }
+     */
+    public List<SignaturePropertyType> getSignatureProperty() {
+        return Collections.unmodifiableList(this.signatureProperty);
+    }
+
+    /**
+     * Gets the value of the id property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignaturePropertyType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignaturePropertyType.java
new file mode 100755
index 0000000..25fd5ef
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignaturePropertyType.java
@@ -0,0 +1,95 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for SignaturePropertyType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="SignaturePropertyType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;choice maxOccurs="unbounded">
+ *         &lt;any/>
+ *       &lt;/choice>
+ *       &lt;attribute name="Target" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *       &lt;attribute name="Id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class SignaturePropertyType {
+
+    protected List<Object> content = new ArrayList<Object>();
+    protected String target;
+    protected String id;
+
+    /**
+     * Gets the value of the content property.
+     *
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link org.w3c.dom.Element } {@link Object } {@link String }
+     */
+    public List<Object> getContent() {
+        return this.content;
+    }
+
+    /**
+     * Gets the value of the target property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getTarget() {
+        return target;
+    }
+
+    /**
+     * Sets the value of the target property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setTarget(String value) {
+        this.target = value;
+    }
+
+    /**
+     * Gets the value of the id property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignatureType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignatureType.java
new file mode 100755
index 0000000..f8f38c1
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignatureType.java
@@ -0,0 +1,144 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for SignatureType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="SignatureType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}SignedInfo"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}SignatureValue"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}KeyInfo" minOccurs="0"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}Object" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class SignatureType {
+
+    protected SignedInfoType signedInfo;
+    protected SignatureValueType signatureValue;
+    protected KeyInfoType keyInfo;
+    protected List<ObjectType> object = new ArrayList<ObjectType>();
+    protected String id;
+
+    /**
+     * Gets the value of the signedInfo property.
+     *
+     * @return possible object is {@link SignedInfoType }
+     */
+    public SignedInfoType getSignedInfo() {
+        return signedInfo;
+    }
+
+    /**
+     * Sets the value of the signedInfo property.
+     *
+     * @param value allowed object is {@link SignedInfoType }
+     */
+    public void setSignedInfo(SignedInfoType value) {
+        this.signedInfo = value;
+    }
+
+    /**
+     * Gets the value of the signatureValue property.
+     *
+     * @return possible object is {@link SignatureValueType }
+     */
+    public SignatureValueType getSignatureValue() {
+        return signatureValue;
+    }
+
+    /**
+     * Sets the value of the signatureValue property.
+     *
+     * @param value allowed object is {@link SignatureValueType }
+     */
+    public void setSignatureValue(SignatureValueType value) {
+        this.signatureValue = value;
+    }
+
+    /**
+     * Gets the value of the keyInfo property.
+     *
+     * @return possible object is {@link KeyInfoType }
+     */
+    public KeyInfoType getKeyInfo() {
+        return keyInfo;
+    }
+
+    /**
+     * Sets the value of the keyInfo property.
+     *
+     * @param value allowed object is {@link KeyInfoType }
+     */
+    public void setKeyInfo(KeyInfoType value) {
+        this.keyInfo = value;
+    }
+
+    public void addObject(ObjectType obj) {
+        this.object.add(obj);
+    }
+
+    public void removeObject(ObjectType obj) {
+        this.object.remove(obj);
+    }
+
+    /**
+     * Gets the value of the object property.
+     *
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link ObjectType }
+     */
+    public List<ObjectType> getObject() {
+        return Collections.unmodifiableList(this.object);
+    }
+
+    /**
+     * Gets the value of the id property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignatureValueType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignatureValueType.java
new file mode 100755
index 0000000..7faf77b
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignatureValueType.java
@@ -0,0 +1,77 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+/**
+ * <p>
+ * Java class for SignatureValueType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="SignatureValueType">
+ *   &lt;simpleContent>
+ *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>base64Binary">
+ *       &lt;attribute name="Id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *     &lt;/extension>
+ *   &lt;/simpleContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class SignatureValueType {
+
+    protected byte[] value;
+    protected String id;
+
+    /**
+     * Gets the value of the value property.
+     *
+     * @return possible object is byte[]
+     */
+    public byte[] getValue() {
+        return value;
+    }
+
+    /**
+     * Sets the value of the value property.
+     *
+     * @param value allowed object is byte[]
+     */
+    public void setValue(byte[] value) {
+        this.value = ((byte[]) value);
+    }
+
+    /**
+     * Gets the value of the id property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignedInfoType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignedInfoType.java
new file mode 100755
index 0000000..1d207f5
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SignedInfoType.java
@@ -0,0 +1,125 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for SignedInfoType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="SignedInfoType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}CanonicalizationMethod"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}SignatureMethod"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}Reference" maxOccurs="unbounded"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class SignedInfoType {
+
+    protected CanonicalizationMethodType canonicalizationMethod;
+    protected SignatureMethodType signatureMethod;
+    protected List<ReferenceType> reference = new ArrayList<ReferenceType>();
+    protected String id;
+
+    /**
+     * Gets the value of the canonicalizationMethod property.
+     *
+     * @return possible object is {@link CanonicalizationMethodType }
+     */
+    public CanonicalizationMethodType getCanonicalizationMethod() {
+        return canonicalizationMethod;
+    }
+
+    /**
+     * Sets the value of the canonicalizationMethod property.
+     *
+     * @param value allowed object is {@link CanonicalizationMethodType }
+     */
+    public void setCanonicalizationMethod(CanonicalizationMethodType value) {
+        this.canonicalizationMethod = value;
+    }
+
+    /**
+     * Gets the value of the signatureMethod property.
+     *
+     * @return possible object is {@link SignatureMethodType }
+     */
+    public SignatureMethodType getSignatureMethod() {
+        return signatureMethod;
+    }
+
+    /**
+     * Sets the value of the signatureMethod property.
+     *
+     * @param value allowed object is {@link SignatureMethodType }
+     */
+    public void setSignatureMethod(SignatureMethodType value) {
+        this.signatureMethod = value;
+    }
+
+    public void add(ReferenceType ref) {
+        this.reference.add(ref);
+    }
+
+    public void remove(ReferenceType ref) {
+        this.reference.remove(ref);
+    }
+
+    /**
+     * Gets the value of the reference property.
+     *
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link ReferenceType }
+     */
+    public List<ReferenceType> getReference() {
+        return Collections.unmodifiableList(this.reference);
+    }
+
+    /**
+     * Gets the value of the id property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SPKIDataType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SPKIDataType.java
new file mode 100755
index 0000000..90adf2d
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/SPKIDataType.java
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for SPKIDataType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="SPKIDataType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence maxOccurs="unbounded">
+ *         &lt;element name="SPKISexp" type="{http://www.w3.org/2001/XMLSchema}base64Binary"/>
+ *         &lt;any/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class SPKIDataType {
+
+    protected List<Object> spkiSexpAndAny = new ArrayList<Object>();
+
+    public void addSPKI(Object obj) {
+        this.spkiSexpAndAny.add(obj);
+    }
+
+    public void removeSPKI(Object obj) {
+        this.spkiSexpAndAny.remove(obj);
+    }
+
+    /**
+     * Gets the value of the spkiSexpAndAny property.
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link org.w3c.dom.Element } {@link Object }
+     */
+    public List<Object> getSPKISexpAndAny() {
+        return Collections.unmodifiableList(this.spkiSexpAndAny);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/TransformsType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/TransformsType.java
new file mode 100755
index 0000000..1bda4d1
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/TransformsType.java
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for TransformsType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="TransformsType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}Transform" maxOccurs="unbounded"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class TransformsType {
+
+    protected List<TransformType> transform = new ArrayList<TransformType>();
+
+    public void addTransformsType(TransformType tt) {
+        this.transform.add(tt);
+    }
+
+    public void removeTransformsType(TransformType tt) {
+        this.transform.remove(tt);
+    }
+
+    /**
+     * Gets the value of the transform property.
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link TransformType }
+     */
+    public List<TransformType> getTransform() {
+        return Collections.unmodifiableList(this.transform);
+    }
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/TransformType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/TransformType.java
new file mode 100755
index 0000000..d8601eb
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/TransformType.java
@@ -0,0 +1,82 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for TransformType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="TransformType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;choice maxOccurs="unbounded" minOccurs="0">
+ *         &lt;any/>
+ *         &lt;element name="XPath" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *       &lt;/choice>
+ *       &lt;attribute name="Algorithm" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class TransformType {
+
+    protected List<Object> content = new ArrayList<Object>();
+    protected URI algorithm;
+
+    public TransformType(URI algorithm) {
+        this.algorithm = algorithm;
+    }
+
+    public void addTransform(Object obj) {
+        this.content.add(obj);
+    }
+
+    public void removeTransform(Object obj) {
+        this.content.remove(obj);
+    }
+
+    /**
+     * Gets the value of the content property.
+     *
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link org.w3c.dom.Element } {@link String } {@link Object }
+     */
+    public List<Object> getContent() {
+        return Collections.unmodifiableList(this.content);
+    }
+
+    /**
+     * Gets the value of the algorithm property.
+     *
+     * @return possible object is {@link String }
+     */
+    public URI getAlgorithm() {
+        return algorithm;
+    }
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/X509CertificateType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/X509CertificateType.java
new file mode 100755
index 0000000..303f753
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/X509CertificateType.java
@@ -0,0 +1,31 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+public class X509CertificateType {
+
+    private byte[] encodedCertificate;
+
+    public byte[] getEncodedCertificate() {
+        return this.encodedCertificate;
+    }
+
+    public void setEncodedCertificate(byte[] encodedCertificate) {
+        this.encodedCertificate = encodedCertificate;
+    }
+}
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/X509DataType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/X509DataType.java
new file mode 100755
index 0000000..02d3255
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/X509DataType.java
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for X509DataType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="X509DataType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence maxOccurs="unbounded">
+ *         &lt;choice>
+ *           &lt;element name="X509IssuerSerial" type="{http://www.w3.org/2000/09/xmldsig#}X509IssuerSerialType"/>
+ *           &lt;element name="X509SKI" type="{http://www.w3.org/2001/XMLSchema}base64Binary"/>
+ *           &lt;element name="X509SubjectName" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *           &lt;element name="X509Certificate" type="{http://www.w3.org/2001/XMLSchema}base64Binary"/>
+ *           &lt;element name="X509CRL" type="{http://www.w3.org/2001/XMLSchema}base64Binary"/>
+ *           &lt;any/>
+ *         &lt;/choice>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class X509DataType {
+
+    protected List<Object> x509IssuerSerialOrX509SKIOrX509SubjectName = new ArrayList<Object>();
+
+    public void add(Object obj) {
+        this.x509IssuerSerialOrX509SKIOrX509SubjectName.add(obj);
+    }
+
+    public void remove(Object obj) {
+        this.x509IssuerSerialOrX509SKIOrX509SubjectName.remove(obj);
+    }
+
+    /**
+     * Gets the value of the x509IssuerSerialOrX509SKIOrX509SubjectName property.
+     *
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link org.w3c.dom.Element } {@link Object }
+     */
+    public List<Object> getDataObjects() {
+        return Collections.unmodifiableList(this.x509IssuerSerialOrX509SKIOrX509SubjectName);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/X509IssuerSerialType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/X509IssuerSerialType.java
new file mode 100755
index 0000000..d137cfa
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmldsig/X509IssuerSerialType.java
@@ -0,0 +1,82 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmldsig;
+
+import java.math.BigInteger;
+
+/**
+ * <p>
+ * Java class for X509IssuerSerialType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="X509IssuerSerialType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="X509IssuerName" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         &lt;element name="X509SerialNumber" type="{http://www.w3.org/2001/XMLSchema}integer"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class X509IssuerSerialType {
+
+    protected String x509IssuerName;
+    protected BigInteger x509SerialNumber;
+
+    /**
+     * Gets the value of the x509IssuerName property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getX509IssuerName() {
+        return x509IssuerName;
+    }
+
+    /**
+     * Sets the value of the x509IssuerName property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setX509IssuerName(String value) {
+        this.x509IssuerName = value;
+    }
+
+    /**
+     * Gets the value of the x509SerialNumber property.
+     *
+     * @return possible object is {@link BigInteger }
+     */
+    public BigInteger getX509SerialNumber() {
+        return x509SerialNumber;
+    }
+
+    /**
+     * Sets the value of the x509SerialNumber property.
+     *
+     * @param value allowed object is {@link BigInteger }
+     */
+    public void setX509SerialNumber(BigInteger value) {
+        this.x509SerialNumber = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/AgreementMethodType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/AgreementMethodType.java
new file mode 100755
index 0000000..fdba750
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/AgreementMethodType.java
@@ -0,0 +1,87 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmlenc;
+
+import org.keycloak.dom.xmlsec.w3.xmldsig.KeyInfoType;
+
+/**
+ * <p>
+ * Java class for AgreementMethodType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="AgreementMethodType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="KA-Nonce" type="{http://www.w3.org/2001/XMLSchema}base64Binary" minOccurs="0"/>
+ *         &lt;any/>
+ *         &lt;element name="OriginatorKeyInfo" type="{http://www.w3.org/2000/09/xmldsig#}KeyInfoType" minOccurs="0"/>
+ *         &lt;element name="RecipientKeyInfo" type="{http://www.w3.org/2000/09/xmldsig#}KeyInfoType" minOccurs="0"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Algorithm" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class AgreementMethodType {
+
+    protected String algorithm;
+
+    public static class AggrementMethod {
+
+        protected byte[] kANonce;
+        protected KeyInfoType originatorKeyInfo;
+        protected KeyInfoType recipientKeyInfo;
+
+        public AggrementMethod(byte[] kANonce, KeyInfoType originatorKeyInfo, KeyInfoType recipientKeyInfo) {
+            this.kANonce = kANonce;
+            this.originatorKeyInfo = originatorKeyInfo;
+            this.recipientKeyInfo = recipientKeyInfo;
+        }
+
+        public byte[] getkANonce() {
+            return kANonce;
+        }
+
+        public KeyInfoType getOriginatorKeyInfo() {
+            return originatorKeyInfo;
+        }
+
+        public KeyInfoType getRecipientKeyInfo() {
+            return recipientKeyInfo;
+        }
+    }
+
+    public AgreementMethodType(String algo) {
+        this.algorithm = algo;
+    }
+
+    /**
+     * Gets the value of the algorithm property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/CipherDataType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/CipherDataType.java
new file mode 100755
index 0000000..3cb220c
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/CipherDataType.java
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmlenc;
+
+/**
+ * <p>
+ * Java class for CipherDataType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="CipherDataType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;choice>
+ *         &lt;element name="CipherValue" type="{http://www.w3.org/2001/XMLSchema}base64Binary"/>
+ *         &lt;element ref="{http://www.w3.org/2001/04/xmlenc#}CipherReference"/>
+ *       &lt;/choice>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class CipherDataType {
+
+    protected byte[] cipherValue;
+    protected CipherReferenceType cipherReference;
+
+    /**
+     * Gets the value of the cipherValue property.
+     *
+     * @return possible object is byte[]
+     */
+    public byte[] getCipherValue() {
+        return cipherValue;
+    }
+
+    /**
+     * Sets the value of the cipherValue property.
+     *
+     * @param value allowed object is byte[]
+     */
+    public void setCipherValue(byte[] value) {
+        this.cipherValue = ((byte[]) value);
+    }
+
+    /**
+     * Gets the value of the cipherReference property.
+     *
+     * @return possible object is {@link CipherReferenceType }
+     */
+    public CipherReferenceType getCipherReference() {
+        return cipherReference;
+    }
+
+    /**
+     * Sets the value of the cipherReference property.
+     *
+     * @param value allowed object is {@link CipherReferenceType }
+     */
+    public void setCipherReference(CipherReferenceType value) {
+        this.cipherReference = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/CipherReferenceType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/CipherReferenceType.java
new file mode 100755
index 0000000..2a2a9d8
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/CipherReferenceType.java
@@ -0,0 +1,78 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmlenc;
+
+import java.net.URI;
+
+/**
+ * <p>
+ * Java class for CipherReferenceType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="CipherReferenceType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;choice>
+ *         &lt;element name="Transforms" type="{http://www.w3.org/2001/04/xmlenc#}TransformsType" minOccurs="0"/>
+ *       &lt;/choice>
+ *       &lt;attribute name="URI" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class CipherReferenceType {
+
+    protected TransformsType transforms;
+    protected URI uri;
+
+    public CipherReferenceType(URI uri) {
+
+    }
+
+    /**
+     * Gets the value of the transforms property.
+     *
+     * @return possible object is {@link TransformsType }
+     */
+    public TransformsType getTransforms() {
+        return transforms;
+    }
+
+    /**
+     * Sets the value of the transforms property.
+     *
+     * @param value allowed object is {@link TransformsType }
+     */
+    public void setTransforms(TransformsType value) {
+        this.transforms = value;
+    }
+
+    /**
+     * Gets the value of the uri property.
+     *
+     * @return possible object is {@link String }
+     */
+    public URI getURI() {
+        return uri;
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptedDataType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptedDataType.java
new file mode 100755
index 0000000..454b501
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptedDataType.java
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmlenc;
+
+/**
+ * <p>
+ * Java class for EncryptedDataType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="EncryptedDataType">
+ *   &lt;complexContent>
+ *     &lt;extension base="{http://www.w3.org/2001/04/xmlenc#}EncryptedType">
+ *     &lt;/extension>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class EncryptedDataType extends EncryptedType {
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptedKeyType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptedKeyType.java
new file mode 100755
index 0000000..e2b2c53
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptedKeyType.java
@@ -0,0 +1,102 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmlenc;
+
+/**
+ * <p>
+ * Java class for EncryptedKeyType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="EncryptedKeyType">
+ *   &lt;complexContent>
+ *     &lt;extension base="{http://www.w3.org/2001/04/xmlenc#}EncryptedType">
+ *       &lt;sequence>
+ *         &lt;element ref="{http://www.w3.org/2001/04/xmlenc#}ReferenceList" minOccurs="0"/>
+ *         &lt;element name="CarriedKeyName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Recipient" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     &lt;/extension>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class EncryptedKeyType extends EncryptedType {
+
+    protected ReferenceList referenceList;
+    protected String carriedKeyName;
+    protected String recipient;
+
+    /**
+     * Gets the value of the referenceList property.
+     *
+     * @return possible object is {@link ReferenceList }
+     */
+    public ReferenceList getReferenceList() {
+        return referenceList;
+    }
+
+    /**
+     * Sets the value of the referenceList property.
+     *
+     * @param value allowed object is {@link ReferenceList }
+     */
+    public void setReferenceList(ReferenceList value) {
+        this.referenceList = value;
+    }
+
+    /**
+     * Gets the value of the carriedKeyName property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getCarriedKeyName() {
+        return carriedKeyName;
+    }
+
+    /**
+     * Sets the value of the carriedKeyName property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setCarriedKeyName(String value) {
+        this.carriedKeyName = value;
+    }
+
+    /**
+     * Gets the value of the recipient property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getRecipient() {
+        return recipient;
+    }
+
+    /**
+     * Sets the value of the recipient property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setRecipient(String value) {
+        this.recipient = value;
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptedType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptedType.java
new file mode 100755
index 0000000..fecd4b0
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptedType.java
@@ -0,0 +1,204 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmlenc;
+
+import org.keycloak.dom.xmlsec.w3.xmldsig.KeyInfoType;
+
+/**
+ * <p>
+ * Java class for EncryptedType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="EncryptedType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="EncryptionMethod" type="{http://www.w3.org/2001/04/xmlenc#}EncryptionMethodType"
+ * minOccurs="0"/>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}KeyInfo" minOccurs="0"/>
+ *         &lt;element ref="{http://www.w3.org/2001/04/xmlenc#}CipherData"/>
+ *         &lt;element ref="{http://www.w3.org/2001/04/xmlenc#}EncryptionProperties" minOccurs="0"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *       &lt;attribute name="Type" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *       &lt;attribute name="MimeType" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="Encoding" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public abstract class EncryptedType {
+
+    protected EncryptionMethodType encryptionMethod;
+    protected KeyInfoType keyInfo;
+    protected CipherDataType cipherData;
+    protected EncryptionPropertiesType encryptionProperties;
+    protected String id;
+    protected String type;
+    protected String mimeType;
+    protected String encoding;
+
+    /**
+     * Gets the value of the encryptionMethod property.
+     *
+     * @return possible object is {@link EncryptionMethodType }
+     */
+    public EncryptionMethodType getEncryptionMethod() {
+        return encryptionMethod;
+    }
+
+    /**
+     * Sets the value of the encryptionMethod property.
+     *
+     * @param value allowed object is {@link EncryptionMethodType }
+     */
+    public void setEncryptionMethod(EncryptionMethodType value) {
+        this.encryptionMethod = value;
+    }
+
+    /**
+     * Gets the value of the keyInfo property.
+     *
+     * @return possible object is {@link KeyInfoType }
+     */
+    public KeyInfoType getKeyInfo() {
+        return keyInfo;
+    }
+
+    /**
+     * Sets the value of the keyInfo property.
+     *
+     * @param value allowed object is {@link KeyInfoType }
+     */
+    public void setKeyInfo(KeyInfoType value) {
+        this.keyInfo = value;
+    }
+
+    /**
+     * Gets the value of the cipherData property.
+     *
+     * @return possible object is {@link CipherDataType }
+     */
+    public CipherDataType getCipherData() {
+        return cipherData;
+    }
+
+    /**
+     * Sets the value of the cipherData property.
+     *
+     * @param value allowed object is {@link CipherDataType }
+     */
+    public void setCipherData(CipherDataType value) {
+        this.cipherData = value;
+    }
+
+    /**
+     * Gets the value of the encryptionProperties property.
+     *
+     * @return possible object is {@link EncryptionPropertiesType }
+     */
+    public EncryptionPropertiesType getEncryptionProperties() {
+        return encryptionProperties;
+    }
+
+    /**
+     * Sets the value of the encryptionProperties property.
+     *
+     * @param value allowed object is {@link EncryptionPropertiesType }
+     */
+    public void setEncryptionProperties(EncryptionPropertiesType value) {
+        this.encryptionProperties = value;
+    }
+
+    /**
+     * Gets the value of the id property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+    /**
+     * Gets the value of the type property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * Sets the value of the type property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setType(String value) {
+        this.type = value;
+    }
+
+    /**
+     * Gets the value of the mimeType property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getMimeType() {
+        return mimeType;
+    }
+
+    /**
+     * Sets the value of the mimeType property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setMimeType(String value) {
+        this.mimeType = value;
+    }
+
+    /**
+     * Gets the value of the encoding property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getEncoding() {
+        return encoding;
+    }
+
+    /**
+     * Sets the value of the encoding property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setEncoding(String value) {
+        this.encoding = value;
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptionMethodType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptionMethodType.java
new file mode 100755
index 0000000..0273ded
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptionMethodType.java
@@ -0,0 +1,89 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmlenc;
+
+import java.math.BigInteger;
+
+/**
+ * <p>
+ * Java class for EncryptionMethodType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="EncryptionMethodType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="KeySize" type="{http://www.w3.org/2001/04/xmlenc#}KeySizeType" minOccurs="0"/>
+ *         &lt;element name="OAEPparams" type="{http://www.w3.org/2001/XMLSchema}base64Binary" minOccurs="0"/>
+ *         &lt;any/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Algorithm" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class EncryptionMethodType {
+
+    protected String algorithm;
+
+    protected EncryptionMethod encryptionMethod;
+
+    public static class EncryptionMethod {
+
+        protected BigInteger keySize;
+        protected byte[] OAEPparams;
+
+        public EncryptionMethod(BigInteger bigInteger, byte[] oAEPparams) {
+            this.keySize = bigInteger;
+            OAEPparams = oAEPparams;
+        }
+
+        public BigInteger getKeySize() {
+            return keySize;
+        }
+
+        public byte[] getOAEPparams() {
+            return OAEPparams;
+        }
+    }
+
+    public EncryptionMethodType(String algo) {
+        this.algorithm = algo;
+    }
+
+    public EncryptionMethod getEncryptionMethod() {
+        return encryptionMethod;
+    }
+
+    public void setEncryptionMethod(EncryptionMethod encryptionMethod) {
+        this.encryptionMethod = encryptionMethod;
+    }
+
+    /**
+     * Gets the value of the algorithm property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getAlgorithm() {
+        return algorithm;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptionPropertiesType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptionPropertiesType.java
new file mode 100755
index 0000000..a91e14d
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptionPropertiesType.java
@@ -0,0 +1,84 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmlenc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for EncryptionPropertiesType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="EncryptionPropertiesType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{http://www.w3.org/2001/04/xmlenc#}EncryptionProperty" maxOccurs="unbounded"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="Id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class EncryptionPropertiesType {
+
+    protected List<EncryptionPropertyType> encryptionProperty = new ArrayList<EncryptionPropertyType>();
+    protected String id;
+
+    public void addEncryptionProperty(EncryptionPropertyType enc) {
+        this.encryptionProperty.add(enc);
+    }
+
+    public void removeEncryptionProperty(EncryptionPropertyType enc) {
+        this.encryptionProperty.remove(enc);
+    }
+
+    /**
+     * Gets the value of the encryptionProperty property.
+     *
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link EncryptionPropertyType }
+     */
+    public List<EncryptionPropertyType> getEncryptionProperty() {
+        return Collections.unmodifiableList(this.encryptionProperty);
+    }
+
+    /**
+     * Gets the value of the id property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptionPropertyType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptionPropertyType.java
new file mode 100755
index 0000000..7f1725e
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/EncryptionPropertyType.java
@@ -0,0 +1,109 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmlenc;
+
+import javax.xml.namespace.QName;
+import java.net.URI;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>
+ * Java class for EncryptionPropertyType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="EncryptionPropertyType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;choice maxOccurs="unbounded">
+ *         &lt;any/>
+ *       &lt;/choice>
+ *       &lt;attribute name="Target" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *       &lt;attribute name="Id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class EncryptionPropertyType {
+
+    protected URI target;
+    protected String id;
+    private Map<QName, String> otherAttributes = new HashMap<QName, String>();
+
+    /**
+     * Gets the value of the target property.
+     *
+     * @return possible object is {@link URI }
+     */
+    public URI getTarget() {
+        return target;
+    }
+
+    /**
+     * Sets the value of the target property.
+     *
+     * @param value allowed object is {@link URI }
+     */
+    public void setTarget(URI value) {
+        this.target = value;
+    }
+
+    /**
+     * Gets the value of the id property.
+     *
+     * @return possible object is {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     *
+     * @param value allowed object is {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+    public void addOtherAttribute(QName key, String val) {
+        this.otherAttributes.put(key, val);
+    }
+
+    public void addOtherAttributes(Map<QName, String> otherMap) {
+        this.otherAttributes.putAll(otherMap);
+    }
+
+    public void removeOtherAttribute(QName key) {
+        this.otherAttributes.remove(key);
+    }
+
+    /**
+     * Gets a map that contains attributes that aren't bound to any typed property on this class.
+     *
+     * @return always non-null
+     */
+    public Map<QName, String> getOtherAttributes() {
+        return Collections.unmodifiableMap(otherAttributes);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/package-info.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/package-info.java
new file mode 100755
index 0000000..58e88e0
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmlenc;
+
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/ReferenceList.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/ReferenceList.java
new file mode 100755
index 0000000..6c80a60
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/ReferenceList.java
@@ -0,0 +1,82 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmlenc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for anonymous complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType>
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;choice maxOccurs="unbounded">
+ *         &lt;element name="DataReference" type="{http://www.w3.org/2001/04/xmlenc#}ReferenceType"/>
+ *         &lt;element name="KeyReference" type="{http://www.w3.org/2001/04/xmlenc#}ReferenceType"/>
+ *       &lt;/choice>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class ReferenceList {
+
+    public static class References {
+
+        private ReferenceType dataReference;
+        private ReferenceType keyReference;
+
+        public References(ReferenceType dataReference, ReferenceType keyReference) {
+            this.dataReference = dataReference;
+            this.keyReference = keyReference;
+        }
+
+        public ReferenceType getDataReference() {
+            return dataReference;
+        }
+
+        public ReferenceType getKeyReference() {
+            return keyReference;
+        }
+    }
+
+    private List<References> referencesList = new ArrayList<References>();
+
+    public void add(References ref) {
+        this.referencesList.add(ref);
+    }
+
+    public void addAll(List<References> refs) {
+        this.referencesList.addAll(refs);
+    }
+
+    public void remove(References ref) {
+        this.referencesList.remove(ref);
+    }
+
+    public List<References> getReferences() {
+        return Collections.unmodifiableList(referencesList);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/ReferenceType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/ReferenceType.java
new file mode 100755
index 0000000..6cb791e
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/ReferenceType.java
@@ -0,0 +1,68 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmlenc;
+
+import java.net.URI;
+
+/**
+ * <p>
+ * Java class for ReferenceType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="ReferenceType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;any/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="URI" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class ReferenceType {
+
+    protected URI uri;
+
+    public Object reference;
+
+    public ReferenceType(URI uri) {
+        this.uri = uri;
+    }
+
+    public Object getReference() {
+        return reference;
+    }
+
+    public void setReference(Object reference) {
+        this.reference = reference;
+    }
+
+    /**
+     * Gets the value of the uri property.
+     *
+     * @return possible object is {@link URI }
+     */
+    public URI getURI() {
+        return uri;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/TransformsType.java b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/TransformsType.java
new file mode 100755
index 0000000..19c3f54
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/dom/xmlsec/w3/xmlenc/TransformsType.java
@@ -0,0 +1,69 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.dom.xmlsec.w3.xmlenc;
+
+import org.keycloak.dom.xmlsec.w3.xmldsig.TransformType;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * Java class for TransformsType complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="TransformsType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}Transform" maxOccurs="unbounded"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+public class TransformsType {
+
+    protected List<TransformType> transform = new ArrayList<TransformType>();
+
+    public void add(TransformType tt) {
+        this.transform.add(tt);
+    }
+
+    public void addAll(List<TransformType> ttlist) {
+        this.transform.addAll(ttlist);
+    }
+
+    public void remove(TransformType tt) {
+        this.transform.remove(tt);
+    }
+
+    /**
+     * Gets the value of the transform property.
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link TransformType }
+     */
+    public List<TransformType> getTransform() {
+        return Collections.unmodifiableList(this.transform);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/constants/GeneralConstants.java b/saml-core/src/main/java/org/keycloak/saml/common/constants/GeneralConstants.java
new file mode 100755
index 0000000..7a7acb3
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/constants/GeneralConstants.java
@@ -0,0 +1,155 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.keycloak.saml.common.constants;
+
+
+/**
+ * Constants
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Oct 8, 2009
+ */
+public interface GeneralConstants {
+    String ASSERTIONS_VALIDITY = "ASSERTIONS_VALIDITY";
+    String CLOCK_SKEW = "CLOCK_SKEW";
+
+    String ASSERTION_ID = "ASSERTION_ID";
+
+    String ASSERTION = "ASSERTION";
+
+    String ATTRIBUTES = "ATTRIBUTES";
+
+    String ATTRIBUTE_KEYS = "ATTRIBUTE_KEYS";
+
+    String ATTRIBUTE_CHOOSE_FRIENDLY_NAME = "ATTRIBUTE_CHOOSE_FRIENDLY_NAME";
+
+    String ATTIBUTE_MANAGER = "ATTRIBUTE_MANAGER";
+
+    String AUDIT_ENABLE = "picketlink.audit.enable";
+
+    String AUDIT_HELPER = "AUDIT_HELPER";
+
+    String AUDIT_SECURITY_DOMAIN = "picketlink.audit.securitydomain";
+
+    String CONFIGURATION = "CONFIGURATION";
+
+    String CONFIG_FILE_LOCATION = "/WEB-INF/picketlink.xml";
+
+    String CONFIG_PROVIDER = "CONFIG_PROVIDER";
+
+    String CONTEXT_PATH = "CONTEXT_PATH";
+
+    String DEPRECATED_CONFIG_FILE_LOCATION = "/WEB-INF/picketlink-idfed.xml";
+
+    String LOCAL_LOGOUT = "LLO";
+
+    String GLOBAL_LOGOUT = "GLO";
+
+    String HANDLER_CONFIG_FILE_LOCATION = "/WEB-INF/picketlink-handlers.xml";
+
+    String IDENTITY_SERVER = "IDENTITY_SERVER";
+
+    String IDENTITY_PARTICIPANT_STACK = "IDENTITY_PARTICIPANT_STACK";
+
+    String IGNORE_SIGNATURES = "IGNORE_SIGNATURES";
+
+    String KEYPAIR = "KEYPAIR";
+
+    String LOGIN_TYPE = "LOGIN_TYPE";
+
+    String LOGOUT_PAGE = "LOGOUT_PAGE";
+
+    String LOGOUT_PAGE_NAME = "/logout.jsp";
+
+    String NAMEID_FORMAT = "NAMEID_FORMAT";
+
+    String PRINCIPAL_ID = "picketlink.principal";
+
+    String RELAY_STATE = "RelayState";
+
+    String ROLES = "ROLES";
+
+    String ROLES_ID = "picketlink.roles";
+
+    String ROLE_GENERATOR = "ROLE_GENERATOR";
+
+    String ROLE_VALIDATOR = "ROLE_VALIDATOR";
+
+    String ROLE_VALIDATOR_IGNORE = "ROLE_VALIDATOR_IGNORE";
+
+    String SAML_REQUEST_KEY = "SAMLRequest";
+
+    String SAML_RESPONSE_KEY = "SAMLResponse";
+
+    String SAML_SIG_ALG_REQUEST_KEY = "SigAlg";
+
+    String SAML_SIGNATURE_REQUEST_KEY = "Signature";
+
+    String SAML_IDP_STRICT_POST_BINDING = "SAML_IDP_STRICT_POST_BINDING";
+
+    // Should JAXP Factory operations cache the TCCL and revert after operation?
+    String TCCL_JAXP = "picketlink.jaxp.tccl";
+
+    String TIMEZONE = "picketlink.timezone";
+
+    String TIMEZONE_DEFAULT = "TIMEZONE_DEFAULT";
+
+    String DECRYPTING_KEY = "DECRYPTING_KEY";
+
+    String SP_SSO_METADATA_DESCRIPTOR = "SP_SSO_METADATA_DESCRIPTOR";
+
+    String IDP_SSO_METADATA_DESCRIPTOR = "IDP_SSO_METADATA_DESCRIPTOR";
+
+    String SSO_METADATA_DESCRIPTOR = "SSO_METADATA_DESCRIPTOR";
+
+    String SENDER_PUBLIC_KEY = "SENDER_PUBLIC_KEY";
+
+    String SIGN_OUTGOING_MESSAGES = "SIGN_OUTGOING_MESSAGES";
+
+    String SUPPORTS_SIGNATURES = "SUPPORTS_SIGNATURES";
+
+    String SESSION_ATTRIBUTE_MAP = "SESSION_ATTRIBUTE_MAP";
+
+    String USERNAME_FIELD = "JBID_USERNAME";
+
+    String PASS_FIELD = "JBID_PASSWORD";
+
+    String AUTH_REQUEST_ID = "AUTH_REQUEST_ID";
+    String ERROR_PAGE_NAME = "/error.jsp";
+    String SAML_ENC_KEY_SIZE = "SAML_ENC_KEY_SIZE";
+    String SAML_ENC_ALGORITHM = "SAML_ENC_ALGORITHM";
+
+    /**
+     * <p>{@link SAML2AuthenticationHandler} configuration option to set the assertion into the {@link
+     * HttpSession}.</p>
+     */
+    String ASSERTION_SESSION_ATTRIBUTE_NAME = "ASSERTION_SESSION_ATTRIBUTE_NAME";
+
+    String X509CERTIFICATE = "X509CERTIFICATE";
+
+    String AUTHN_CONTEXT_CLASSES = "AUTHN_CONTEXT_CLASSES";
+    String REQUESTED_AUTHN_CONTEXT_COMPARISON = "REQUESTED_AUTHN_CONTEXT_COMPARISON";
+
+    String BASE64_ENCODE_WSTRUST_SECRET_KEY = "picketlink.wstrust.base64_encode_wstrust_secret_key";
+
+    String HTTP_HEADER_X_REQUESTED_WITH = "X-Requested-With";
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/constants/JBossSAMLConstants.java b/saml-core/src/main/java/org/keycloak/saml/common/constants/JBossSAMLConstants.java
new file mode 100755
index 0000000..219042b
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/constants/JBossSAMLConstants.java
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.constants;
+
+/**
+ * SAML Constants
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 10, 2008
+ */
+public enum JBossSAMLConstants {
+    ADDRESS("Address"), ADDITIONAL_METADATA_LOCATION("AdditionalMetadataLocation"), AFFILIATION_DESCRIPTOR(
+            "AffiliationDescriptor"), ALLOW_CREATE("AllowCreate"), ARTIFACT("Artifact"), ARTIFACT_RESOLVE("ArtifactResolve"), ARTIFACT_RESPONSE(
+            "ArtifactResponse"), ARTIFACT_RESOLUTION_SERVICE("ArtifactResolutionService"), ASSERTION("Assertion"), ASSERTION_CONSUMER_SERVICE(
+            "AssertionConsumerService"), ASSERTION_CONSUMER_SERVICE_URL("AssertionConsumerServiceURL"), ASSERTION_CONSUMER_SERVICE_INDEX(
+            "AssertionConsumerServiceIndex"), ASSERTION_ID_REQUEST_SERVICE("AssertionIDRequestService"), ATTRIBUTE("Attribute"), ATTRIBUTE_QUERY(
+            "AttributeQuery"), ATTRIBUTE_AUTHORITY_DESCRIPTOR("AttributeAuthorityDescriptor"), ATTRIBUTE_CONSUMING_SERVICE(
+            "AttributeConsumingService"), ATTRIBUTE_CONSUMING_SERVICE_INDEX("AttributeConsumingServiceIndex"), ATTRIBUTE_SERVICE(
+            "AttributeService"), ATTRIBUTE_STATEMENT("AttributeStatement"), ATTRIBUTE_VALUE("AttributeValue"), AUDIENCE(
+            "Audience"), AUDIENCE_RESTRICTION("AudienceRestriction"), AUTHN_CONTEXT("AuthnContext"), AUTHENTICATING_AUTHORITY(
+            "AuthenticatingAuthority"), AUTHN_AUTHORITY_DESCRIPTOR("AuthnAuthorityDescriptor"), AUTHN_CONTEXT_CLASS_REF(
+            "AuthnContextClassRef"), AUTHN_CONTEXT_DECLARATION("AuthnContextDecl"), AUTHN_CONTEXT_DECLARATION_REF(
+            "AuthnContextDeclRef"), AUTHN_INSTANT("AuthnInstant"), AUTHN_REQUEST("AuthnRequest"), AUTHN_STATEMENT(
+            "AuthnStatement"), AUTHN_REQUESTS_SIGNED("AuthnRequestsSigned"), BASEID("BaseID"), BINDING("Binding"), CACHE_DURATION(
+            "cacheDuration"), COMPANY("Company"), CONDITIONS("Conditions"), COMPARISON("Comparison"), CONSENT("Consent"), CONTACT_PERSON("ContactPerson"), CONTACT_TYPE(
+            "contactType"), DESTINATION("Destination"), DNS_NAME("DNSName"), EMAIL_ADDRESS("EmailAddress"), ENCODING("Encoding"), ENCRYPTED_ASSERTION(
+            "EncryptedAssertion"), ENCRYPTED_ID("EncryptedID"), ENTITY_ID("entityID"), ENTITY_DESCRIPTOR("EntityDescriptor"), ENTITIES_DESCRIPTOR(
+            "EntitiesDescriptor"), EXTENSIONS("Extensions"), FORMAT("Format"), FRIENDLY_NAME("FriendlyName"), FORCE_AUTHN(
+            "ForceAuthn"), GIVEN_NAME("GivenName"), ID("ID"), IDP_SSO_DESCRIPTOR("IDPSSODescriptor"), INDEX("index"), INPUT_CONTEXT_ONLY(
+            "InputContextOnly"), IN_RESPONSE_TO("InResponseTo"), ISDEFAULT("isDefault"), IS_REQUIRED("isRequired"), IS_PASSIVE(
+            "IsPassive"), ISSUE_INSTANT("IssueInstant"), ISSUER("Issuer"), KEY_DESCRIPTOR("KeyDescriptor"), KEY_INFO("KeyInfo"), ENCRYPTION_METHOD("EncryptionMethod"), LANG(
+            "lang"), LANG_EN("en"), LOCATION("Location"), LOGOUT_REQUEST("LogoutRequest"), LOGOUT_RESPONSE("LogoutResponse"), MANAGE_NAMEID_SERVICE(
+            "ManageNameIDService"), METADATA_MIME("application/samlmetadata+xml"), METHOD("Method"), NAME("Name"), NAME_FORMAT(
+            "NameFormat"), NAMEID("NameID"), NAMEID_FORMAT("NameIDFormat"), NAMEID_MAPPING_SERVICE("NameIDMappingService"), NAMEID_POLICY(
+            "NameIDPolicy"), NAME_QUALIFIER("NameQualifier"), NOT_BEFORE("NotBefore"), NOT_ON_OR_AFTER("NotOnOrAfter"), ORGANIZATION(
+            "Organization"), ORGANIZATION_NAME("OrganizationName"), ORGANIZATION_DISPLAY_NAME("OrganizationDisplayName"), ORGANIZATION_URL(
+            "OrganizationURL"), PDP_DESCRIPTOR("PDPDescriptor"), PROTOCOL_BINDING("ProtocolBinding"), PROTOCOL_SUPPORT_ENUMERATION(
+            "protocolSupportEnumeration"), PROVIDER_NAME("ProviderName"), REQUESTED_AUTHN_CONTEXT("RequestedAuthnContext"), REASON(
+            "Reason"), RECIPIENT("Recipient"), REQUEST("Request"), REQUESTED_ATTRIBUTE("RequestedAttribute"), REQUEST_ABSTRACT(
+            "RequestAbstract"), RESPONSE("Response"), RESPONSE_LOCATION("ResponseLocation"), RETURN_CONTEXT("ReturnContext"), SESSION_INDEX(
+            "SessionIndex"), SERVICE_NAME("ServiceName"), SERVICE_DESCRIPTION("ServiceDescription"), SP_PROVIDED_ID(
+            "SPProvidedID"), SP_NAME_QUALIFIER("SPNameQualifier"), SP_SSO_DESCRIPTOR("SPSSODescriptor"), SIGNATURE("Signature"), SIGNATURE_SHA1_WITH_DSA(
+            "http://www.w3.org/2000/09/xmldsig#dsa-sha1"), SIGNATURE_SHA1_WITH_RSA("http://www.w3.org/2000/09/xmldsig#rsa-sha1"), SINGLE_SIGNON_SERVICE(
+            "SingleSignOnService"), SINGLE_LOGOUT_SERVICE("SingleLogoutService"), STATEMENT("Statement"), STATUS("Status"), STATUS_CODE(
+            "StatusCode"), STATUS_DETAIL("StatusDetail"), STATUS_MESSAGE("StatusMessage"), STATUS_RESPONSE_TYPE(
+            "StatusResponseType"), SUBJECT("Subject"), SUBJECT_CONFIRMATION("SubjectConfirmation"), SUBJECT_CONFIRMATION_DATA(
+            "SubjectConfirmationData"), SUBJECT_LOCALITY("SubjectLocality"), SURNAME("SurName"), TELEPHONE_NUMBER(
+            "TelephoneNumber"), TYPE("type"), USE("use"), VALUE("Value"), VALID_UNTIL("validUntil"), VERSION("Version"), VERSION_2_0(
+            "2.0"), WANT_AUTHN_REQUESTS_SIGNED("WantAuthnRequestsSigned"), WANT_ASSERTIONS_SIGNED("WantAssertionsSigned"), XACML_AUTHZ_DECISION_QUERY(
+            "XACMLAuthzDecisionQuery"), XACML_AUTHZ_DECISION_QUERY_TYPE("XACMLAuthzDecisionQueryType"), XACML_AUTHZ_DECISION_STATEMENT_TYPE(
+            "XACMLAuthzDecisionStatementType"), HTTP_POST_BINDING("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"), ONE_TIME_USE ("OneTimeUse"),
+            UNSOLICITED_RESPONSE_TARGET("TARGET"), UNSOLICITED_RESPONSE_SAML_VERSION("SAML_VERSION"), UNSOLICITED_RESPONSE_SAML_BINDING("SAML_BINDING"),
+            ROLE_DESCRIPTOR("RoleDescriptor"),
+            REQUEST_AUTHENTICATED("RequestAuthenticated");
+
+    private String name;
+
+    private JBossSAMLConstants(String val) {
+        this.name = val;
+    }
+
+    public String get() {
+        return this.name;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/constants/JBossSAMLURIConstants.java b/saml-core/src/main/java/org/keycloak/saml/common/constants/JBossSAMLURIConstants.java
new file mode 100755
index 0000000..ad7bee5
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/constants/JBossSAMLURIConstants.java
@@ -0,0 +1,132 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.constants;
+
+/**
+ * Define the constants based on URI
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 10, 2008
+ */
+public enum JBossSAMLURIConstants {
+    AC_PASSWORD_PROTECTED_TRANSPORT("urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"), AC_PASSWORD(
+            "urn:oasis:names:tc:SAML:2.0:ac:classes:Password"), AC_TLS_CLIENT(
+            "urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient"), AC_PREVIOUS_SESSION(
+            "urn:oasis:names:tc:SAML:2.0:ac:classes:PreviousSession"), AC_UNSPECIFIED(
+            "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified"), AC_IP(
+            "urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocol"),
+
+    ASSERTION_NSURI("urn:oasis:names:tc:SAML:2.0:assertion"), ATTRIBUTE_FORMAT_BASIC(
+            "urn:oasis:names:tc:SAML:2.0:attrname-format:basic"), ATTRIBUTE_FORMAT_URI(
+            "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"),
+
+    BEARER("urn:oasis:names:tc:SAML:2.0:cm:bearer"),
+
+    CLAIMS_EMAIL_ADDRESS_2005("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"), CLAIMS_EMAIL_ADDRESS(
+            "http://schemas.xmlsoap.org/claims/EmailAddress"), CLAIMS_GIVEN_NAME(
+            "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"), CLAIMS_NAME(
+            "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"), CLAIMS_USER_PRINCIPAL_NAME_2005(
+            "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"), CLAIMS_USER_PRINCIPAL_NAME(
+            "http://schemas.xmlsoap.org/claims/UPN"), CLAIMS_COMMON_NAME("http://schemas.xmlsoap.org/claims/CommonName"), CLAIMS_GROUP(
+            "http://schemas.xmlsoap.org/claims/Group"), CLAIMS_ROLE(
+            "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"), CLAIMS_SURNAME(
+            "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"), CLAIMS_PRIVATE_ID(
+            "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier"), CLAIMS_NAME_IDENTIFIER(
+            "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"), CLAIMS_AUTHENTICATION_METHOD(
+            "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod"), CLAIMS_DENY_ONLY_GROUP_SID(
+            "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/denyonlysid"), CLAIMS_DENY_ONLY_PRIMARY_SID(
+            "http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarysid"), CLAIMS_DENY_ONLY_PRIMARY_GROUP_SID(
+            "http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarygroupsid"), CLAIMS_GROUP_SID(
+            "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid"), CLAIMS_PRIMARY_GROUP_SID(
+            "http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid"), CLAIMS_PRIMARY_SID(
+            "http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid"), CLAIMS_WINDOWS_ACCOUNT_NAME(
+            "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"), CLAIMS_PUID(
+            "http://schemas.xmlsoap.org/claims/PUID"),
+
+    HOLDER_OF_KEY("urn:oasis:names:tc:SAML:2.0:cm:holder-of-key"),
+
+    METADATA_NSURI("urn:oasis:names:tc:SAML:2.0:metadata"), METADATA_HTTP_REDIRECT_BINDING(
+            "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"),
+
+    NAMEID_FORMAT_TRANSIENT("urn:oasis:names:tc:SAML:2.0:nameid-format:transient"), NAMEID_FORMAT_PERSISTENT(
+            "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"), NAMEID_FORMAT_UNSPECIFIED(
+            "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"), NAMEID_FORMAT_EMAIL(
+            "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"), NAMEID_FORMAT_X509SUBJECTNAME(
+            "urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName"), NAMEID_FORMAT_WINDOWS_DOMAIN_NAME(
+            "urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName"), NAMEID_FORMAT_KERBEROS(
+            "urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos"), NAMEID_FORMAT_ENTITY(
+            "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"),
+
+    PROTOCOL_NSURI("urn:oasis:names:tc:SAML:2.0:protocol"),
+    ECP_PROFILE("urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp"),
+    PAOS_BINDING("urn:liberty:paos:2003-08"),
+
+    SIGNATURE_DSA_SHA1("http://www.w3.org/2000/09/xmldsig#dsa-sha1"), SIGNATURE_RSA_SHA1(
+            "http://www.w3.org/2000/09/xmldsig#rsa-sha1"),
+
+    SAML_HTTP_POST_BINDING("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"),
+    SAML_HTTP_SOAP_BINDING("urn:oasis:names:tc:SAML:2.0:bindings:SOAP"),
+    SAML_HTTP_REDIRECT_BINDING("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"),
+
+    SAML_11_NS("urn:oasis:names:tc:SAML:1.0:assertion"),
+
+    SUBJECT_CONFIRMATION_BEARER("urn:oasis:names:tc:SAML:2.0:cm:bearer"),
+
+    STATUS_AUTHNFAILED("urn:oasis:names:tc:SAML:2.0:status:AuthnFailed"), STATUS_INVALID_ATTRNAMEVAL(
+            "urn:oasis:names:tc:SAML:2.0:status:InvalidAttrnameOrValue"), STATUS_INVALID_NAMEIDPOLICY(
+            "urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy"), STATUS_NOAUTHN_CTX(
+            "urn:oasis:names:tc:SAML:2.0:status:NoAuthnContext"), STATUS_NO_AVAILABLE_IDP(
+            "urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP"), STATUS_NO_PASSIVE(
+            "urn:oasis:names:tc:SAML:2.0:status:NoPassive"), STATUS_NO_SUPPORTED_IDP(
+            "urn:oasis:names:tc:SAML:2.0:status:NoSupportedIDP"), STATUS_PARTIAL_LOGOUT(
+            "urn:oasis:names:tc:SAML:2.0:status:PartialLogout"), STATUS_PROXYCOUNT_EXCEEDED(
+            "urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded"), STATUS_REQUEST_DENIED(
+            "urn:oasis:names:tc:SAML:2.0:status:RequestDenied"), STATUS_REQUEST_UNSUPPORTED(
+            "urn:oasis:names:tc:SAML:2.0:status:RequestUnsupported"), STATUS_REQUEST_VERSION_DEPRECATED(
+            "urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated"), STATUS_REQUEST_VERSION_2HIGH(
+            "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooHigh"), STATUS_REQUEST_VERSION_2LOW(
+            "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooLow"), STATUS_RESOURCE_NOT_RECOGNIZED(
+            "urn:oasis:names:tc:SAML:2.0:status:ResourceNotRecognized"), STATUS_2MANY_RESPONSES(
+            "urn:oasis:names:tc:SAML:2.0:status:TooManyResponses"), STATUS_UNKNOWN_ATTR_PROFILE(
+            "urn:oasis:names:tc:SAML:2.0:status:UnknownAttributeProfile"), STATUS_UNKNOWN_PRINCIPAL(
+            "urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal"), STATUS_UNSUPPORTED_BINDING(
+            "urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding"),
+
+    STATUS_REQUESTOR("urn:oasis:names:tc:SAML:2.0:status:Requestor"), STATUS_RESPONDER(
+            "urn:oasis:names:tc:SAML:2.0:status:Responder"), STATUS_SUCCESS("urn:oasis:names:tc:SAML:2.0:status:Success"), STATUS_VERSION_MISMATCH(
+            "urn:oasis:names:tc:SAML:2.0:status:VersionMismatch"),
+
+    TRANSFORM_ENVELOPED_SIGNATURE("http://www.w3.org/2000/09/xmldsig#enveloped-signature"), TRANSFORM_C14N_EXCL_OMIT_COMMENTS(
+            "http://www.w3.org/2001/10/xml-exc-c14n#WithComments"),
+
+    XSI_PREFIX("xsi"), X500_PREFIX("x500"), X500_NSURI("urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500"), XACML_NSURI(
+            "urn:oasis:names:tc:xacml:2.0:context:schema:os"), XACML_SAML_NSURI("urn:oasis:xacml:2.0:saml:assertion:schema:os"), XACML_SAML_PROTO_NSURI(
+            "urn:oasis:xacml:2.0:saml:protocol:schema:os"), XML("http://www.w3.org/XML/1998/namespace"), XMLSCHEMA_NSURI(
+            "http://www.w3.org/2001/XMLSchema"), XMLDSIG_NSURI("http://www.w3.org/2000/09/xmldsig#"), XMLENC_NSURI(
+            "http://www.w3.org/2001/04/xmlenc#"), XSI_NSURI("http://www.w3.org/2001/XMLSchema-instance");
+
+    private String uri = null;
+
+    private JBossSAMLURIConstants(String uristr) {
+        this.uri = uristr;
+    }
+
+    public String get() {
+        return this.uri;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/constants/PicketLinkCommonConstants.java b/saml-core/src/main/java/org/keycloak/saml/common/constants/PicketLinkCommonConstants.java
new file mode 100755
index 0000000..62162ca
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/constants/PicketLinkCommonConstants.java
@@ -0,0 +1,30 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.constants;
+
+/**
+ * Common Constants
+ * @author anil saldhana
+ * @since Jan 28, 2013
+ */
+public interface PicketLinkCommonConstants {
+
+    String PBE_ALGORITHM = "PBEwithMD5andDES";
+    // Prefix to indicate a particular configuration property value is masked
+    String PASS_MASK_PREFIX = "MASK-";
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/constants/SAMLAuthenticationContextClass.java b/saml-core/src/main/java/org/keycloak/saml/common/constants/SAMLAuthenticationContextClass.java
new file mode 100755
index 0000000..284bd73
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/constants/SAMLAuthenticationContextClass.java
@@ -0,0 +1,63 @@
+package org.keycloak.saml.common.constants;
+
+/**
+ * <p>A enum that maps a alias for each SAML Authentication Context Class.</p>
+ *
+ * @author pedroigor
+ */
+public enum SAMLAuthenticationContextClass {
+
+    INTERNET_PROTOCOL("internetProtocol", "urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocol"),
+    INTERNET_PROTOCOL_PASSWORD("internetProtocolPassword", "urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocolPassword"),
+    KERBEROS("kerberos", "urn:oasis:names:tc:SAML:2.0:ac:classes:Kerberos"),
+    MOBILE_ONE_FACTOR_UNREGISTERED("mobileOneFactorUnregistered", "urn:oasis:names:tc:SAML:2.0:ac:classes:MobileOneFactorUnregistered"),
+    MOBILE_TWO_FACTOR_UNREGISTERED("mobileTwoFactorUnregistered", "urn:oasis:names:tc:SAML:2.0:ac:classes:MobileTwoFactorUnregistered"),
+    MOBILE_ONE_FACTOR_CONTRACT("mobileOneFactorContract", "urn:oasis:names:tc:SAML:2.0:ac:classes:MobileOneFactorContract"),
+    MOBILE_TWO_FACTOR_CONTRACT("mobileTwoFactorContract", "urn:oasis:names:tc:SAML:2.0:ac:classes:MobileTwoFactorContract"),
+    PASSWORD("password", "urn:oasis:names:tc:SAML:2.0:ac:classes:password"),
+    PASSWORD_PROTECTED_TRANSPORT("passwordProtectedTransport", "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"),
+    PREVIOUS_SESSION("previousSession", "urn:oasis:names:tc:SAML:2.0:ac:classes:PreviousSession"),
+    X509("X509", "urn:oasis:names:tc:SAML:2.0:ac:classes:X509"),
+    PGP("PGP", "urn:oasis:names:tc:SAML:2.0:ac:classes:PGP"),
+    SPKI("SPKI", "urn:oasis:names:tc:SAML:2.0:ac:classes:SPKI"),
+    XMLDSig("XMLDSig", "urn:oasis:names:tc:SAML:2.0:ac:classes:XMLDSig"),
+    SMARTCARD("smartcard", "urn:oasis:names:tc:SAML:2.0:ac:classes:Smartcard"),
+    SMARTCARD_PKI("smartcardPKI", "urn:oasis:names:tc:SAML:2.0:ac:classes:SmartcardPKI"),
+    SOFTWARE_PKI("softwarePKI", "urn:oasis:names:tc:SAML:2.0:ac:classes:SoftwarePKI"),
+    TELEPHONY("telephony", "urn:oasis:names:tc:SAML:2.0:ac:classes:Telephony"),
+    NOMAD_TELEPHONY("nomadTelephony", "urn:oasis:names:tc:SAML:2.0:ac:classes:NomadTelephony"),
+    PERSONAL_TELEPHONY("personalTelephony", "urn:oasis:names:tc:SAML:2.0:ac:classes:PersonalTelephony"),
+    AUTHENTICATED_TELEPHONY("authenticatedTelephony", "urn:oasis:names:tc:SAML:2.0:ac:classes:AuthenticatedTelephony"),
+    SECURE_REMOTE_PASSWORD("secureRemotePassword", "urn:oasis:names:tc:SAML:2.0:ac:classes:SecureRemotePassword"),
+    TLSClient("TLSClient", "urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient"),
+    TIME_SYNC_TOKEN("timeSyncToken", "urn:oasis:names:tc:SAML:2.0:ac:classes:TimeSyncToken"),
+    UNSPECIFIED("unspecified", "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified");
+
+    private final String alias;
+    private final String fqn;
+
+    SAMLAuthenticationContextClass(final String alias, final String fqn) {
+        this.alias = alias;
+        this.fqn = fqn;
+    }
+
+    public String getAlias() {
+        return this.alias;
+    }
+
+    public String getFqn() {
+        return this.fqn;
+    }
+
+    public static SAMLAuthenticationContextClass forAlias(String alias) {
+        if (alias != null) {
+            for (SAMLAuthenticationContextClass contextClass: values()) {
+                if (contextClass.getAlias().equals(alias.trim())) {
+                    return contextClass;
+                }
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/constants/WSTrustConstants.java b/saml-core/src/main/java/org/keycloak/saml/common/constants/WSTrustConstants.java
new file mode 100755
index 0000000..33e86ca
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/constants/WSTrustConstants.java
@@ -0,0 +1,246 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.keycloak.saml.common.constants;
+
+import javax.xml.namespace.QName;
+
+/**
+ * <p> This class defines the constants used throughout the WS-Trust implementation code. </p>
+ *
+ * @author <a href="mailto:sguilhen@redhat.com">Stefan Guilhen</a>
+ * @author <a href="mailto:asaldhan@redhat.com">Anil Saldhana</a>
+ */
+public interface WSTrustConstants {
+
+    String BASE_NAMESPACE = "http://docs.oasis-open.org/ws-sx/ws-trust/200512";
+
+    String PREFIX = "wst";
+
+    // WS-Trust request types
+    String BATCH_ISSUE_REQUEST = BASE_NAMESPACE + "/BatchIssue";
+
+    String ISSUE_REQUEST = BASE_NAMESPACE + "/Issue";
+
+    String RENEW_REQUEST = BASE_NAMESPACE + "/Renew";
+
+    String CANCEL_REQUEST = BASE_NAMESPACE + "/Cancel";
+
+    String VALIDATE_REQUEST = BASE_NAMESPACE + "/Validate";
+
+    String BATCH_VALIDATE_REQUEST = BASE_NAMESPACE + "/BatchValidate";
+
+    // WS-Trust validation constants.
+    String STATUS_TYPE = BASE_NAMESPACE + "/RSTR/Status";
+
+    String STATUS_CODE_VALID = BASE_NAMESPACE + "/status/valid";
+
+    String STATUS_CODE_INVALID = BASE_NAMESPACE + "/status/invalid";
+
+    // WS-Trust key types.
+    String KEY_TYPE_BEARER = BASE_NAMESPACE + "/Bearer";
+
+    String KEY_TYPE_SYMMETRIC = BASE_NAMESPACE + "/SymmetricKey";
+
+    String KEY_TYPE_PUBLIC = BASE_NAMESPACE + "/PublicKey";
+
+    // WS-Trust binary secret types.
+    String BS_TYPE_ASYMMETRIC = BASE_NAMESPACE + "/AsymmetricKey";
+
+    String BS_TYPE_SYMMETRIC = BASE_NAMESPACE + "/SymmetricKey";
+
+    String BS_TYPE_NONCE = BASE_NAMESPACE + "/Nonce";
+
+    // WS-Trust computed key types.
+    String CK_PSHA1 = BASE_NAMESPACE + "/CK/PSHA1";
+
+    // WSS namespaces values.
+    String WSA_NS = "http://www.w3.org/2005/08/addressing";
+
+    String WSP_NS = "http://schemas.xmlsoap.org/ws/2004/09/policy";
+
+    String WSP_15_NS = "http://www.w3.org/ns/ws-policy";
+
+    String WSU_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
+
+    String WSSE_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
+
+    String WSSE11_NS = "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd";
+
+    String XENC_NS = "http://www.w3.org/2001/04/xmlenc#";
+
+    String DSIG_NS = "http://www.w3.org/2000/09/xmldsig#";
+
+    String SAML2_ASSERTION_NS = "urn:oasis:names:tc:SAML:2.0:assertion";
+
+    // WSS Fault codes
+    QName SECURITY_TOKEN_UNAVAILABLE = new QName(WSSE_NS, "SecurityTokenUnavailable");
+
+    QName INVALID_SECURITY_TOKEN = new QName(WSSE_NS, "InvalidSecurityToken");
+
+    QName INVALID_SECURITY = new QName(WSSE_NS, "InvalidSecurity");
+
+    QName FAILED_AUTHENTICATION = new QName(WSSE_NS, "FailedAuthentication");
+
+    // Token Types
+    String RSTR_STATUS_TOKEN_TYPE = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTR/Status";
+
+    // Element Names
+    String BINARY_SECRET = "BinarySecret";
+
+    String CREATED = "Created";
+
+    String COMPUTED_KEY_ALGORITHM = "ComputedKeyAlgorithm";
+
+    String ENTROPY = "Entropy";
+
+    String EXPIRES = "Expires";
+
+    String ISSUER = "Issuer";
+
+    String ON_BEHALF_OF = "OnBehalfOf";
+
+    String COMPUTED_KEY = "ComputedKey";
+
+    String KEY_SIZE = "KeySize";
+
+    String KEY_TYPE = "KeyType";
+
+    String LIFETIME = "Lifetime";
+
+    String RENEWING = "Renewing";
+
+    String RST = "RequestSecurityToken";
+
+    String RSTR = "RequestSecurityTokenResponse";
+
+    String RST_COLLECTION = "RequestSecurityTokenCollection";
+
+    String RSTR_COLLECTION = "RequestSecurityTokenResponseCollection";
+
+    String REQUESTED_TOKEN = "RequestedSecurityToken";
+
+    String REQUESTED_TOKEN_CANCELLED = "RequestedTokenCancelled";
+
+    String REQUESTED_PROOF_TOKEN = "RequestedProofToken";
+
+    String REQUESTED_ATTACHED_REFERENCE = "RequestedAttachedReference";
+
+    String REQUESTED_UNATTACHED_REFERENCE = "RequestedUnattachedReference";
+
+    String REQUEST_TYPE = "RequestType";
+
+    String TOKEN_TYPE = "TokenType";
+
+    String CANCEL_TARGET = "CancelTarget";
+
+    String RENEW_TARGET = "RenewTarget";
+
+    String SECONDARY_PARAMETERS = "SecondaryParameters";
+
+    String VALIDATE_TARGET = "ValidateTarget";
+
+    String USE_KEY = "UseKey";
+
+    String STATUS = "Status";
+
+    String CODE = "Code";
+
+    String REASON = "Reason";
+
+    // Attribute Names
+    String ALLOW = "Allow";
+
+    String OK = "OK";
+
+    String RST_CONTEXT = "Context";
+
+    String TYPE = "Type";
+
+    String VALUE_TYPE = "ValueType";
+
+    public interface XMLDSig {
+
+        String DSIG_NS = "http://www.w3.org/2000/09/xmldsig#";
+
+        String EXPONENT = "Exponent";
+
+        String KEYINFO = "KeyInfo";
+
+        String KEYVALUE = "KeyValue";
+
+        String MODULUS = "Modulus";
+
+        String DSIG_PREFIX = "ds";
+
+        String RSA_KEYVALUE = "RSAKeyValue";
+
+        String DSA_KEYVALUE = "DSAKeyValue";
+
+        String X509DATA = "X509Data";
+
+        String X509CERT = "X509Certificate";
+
+        String P = "P";
+        String Q = "Q";
+        String G = "G";
+        String Y = "Y";
+        String SEED = "Seed";
+        String PGEN_COUNTER = "PgenCounter";
+    }
+
+    public interface XMLEnc {
+
+        String XMLENC_NS = "http://www.w3.org/2001/04/xmlenc#";
+
+        String ENCRYPTED_KEY = "EncryptedKey";
+    }
+
+    public interface WSSE {
+
+        String ID = "Id";
+
+        String KEY_IDENTIFIER = "KeyIdentifier";
+
+        String KEY_IDENTIFIER_VALUETYPE_SAML = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID";
+
+        String REFERENCE = "Reference";
+
+        String PREFIX = "wsse";
+
+        String PREFIX_11 = "wsse11";
+
+        // http://www.ws-i.org/Profiles/KerberosTokenProfile-1.0.html#Kerberos_Security_Token_URI
+        String KERBEROS = "http://docs.oasis-open.org/wss/2005/xx/oasis-2005xx-wss-kerberos-token-profile-1.1#GSS_Kerberosv5_AP_REQ";
+
+        String SECURITY_TOKEN_REFERENCE = "SecurityTokenReference";
+
+        String BINARY_SECURITY_TOKEN = "BinarySecurityToken";
+
+        String USERNAME_TOKEN = "UsernameToken";
+
+        String URI = "URI";
+
+        String VALUE_TYPE = "ValueType";
+
+        String ENCODING_TYPE = "EncodingType";
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/ErrorCodes.java b/saml-core/src/main/java/org/keycloak/saml/common/ErrorCodes.java
new file mode 100755
index 0000000..70fc27d
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/ErrorCodes.java
@@ -0,0 +1,206 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common;
+
+/**
+ * Error Codes for PicketLink https://docs.jboss.org/author/display/PLINK/PicketLink+Error+Codes
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Aug 4, 2011
+ */
+public interface ErrorCodes {
+
+    String ASSERTION_RENEWAL_EXCEPTION = "PL00103:Assertion Renewal Exception:";
+
+    String AUDIT_MANAGER_NULL = "PL00028: Audit Manager Is Not Set";
+
+    String AUTHENTICATOR_DOES_NOT_HANDLE_ENC = "PL00027: Authenticator does not handle encryption";
+
+    String AUTHN_REQUEST_ID_VERIFICATION_FAILED = "PL00104:Authn Request ID verification failed:";
+
+    String CLASS_NOT_LOADED = "PL00085: Class Not Loaded:";
+
+    String CANNOT_CREATE_INSTANCE = "PL00086: Cannot create instance of:";
+
+    String DOM_MISSING_DOC_ELEMENT = "PL00098: Missing Document Element:";
+
+    String DOM_MISSING_ELEMENT = "PL00099: Missing Element:";
+
+    String ENCRYPTION_PROCESS_FAILURE = "PL00101: Encryption Process Failure:";
+
+    String EXPIRED_ASSERTION = "PL00079: Assertion has expired:";
+
+    String EXPECTED_XSI = "PL00072: Parser: Expected xsi:type";
+
+    String EXPECTED_TAG = "PL00066: Parser : Expected start tag:";
+
+    String EXPECTED_TEXT_VALUE = "PL00071: Parser: Expected text value:";
+
+    String EXPECTED_END_TAG = "PL00066: Parser : Expected end tag:";
+
+    String FAILED_PARSING = "PL00067: Parsing has failed:";
+
+    String FILE_NOT_LOCATED = "PL00075: File could not be located :";
+
+    String IDP_AUTH_FAILED = "PL00015: IDP Authentication Failed:";
+
+    String IDP_WEBBROWSER_VALVE_ALREADY_STARTED = "PL00021: IDPWebBrowserSSOValve already Started";
+
+    String IDP_WEBBROWSER_VALVE_CONF_FILE_MISSING = "PL00017: Configuration File missing:";
+
+    String IDP_WEBBROWSER_VALVE_NOT_STARTED = "PL00024: IDPWebBrowserSSOValve NotStarted";
+
+    String ILLEGAL_METHOD_CALLED = "PL00020: Illegal Method Called";
+
+    String INVALID_ASSERTION = "PL00080: Invalid Assertion:";
+
+    String INVALID_DIGITAL_SIGNATURE = "PL00009: Invalid Digital Signature:";
+
+    String INJECTED_VALUE_MISSING = "PL00077: Injected Value Missing:";
+
+    String ISSUER_INFO_MISSING_STATUS_CODE = "PL00085: IssuerInfo missing status code :";
+
+    String KEYSTOREKEYMGR_DOMAIN_ALIAS_MISSING = "PL00058: KeyStoreKeyManager : Domain Alias missing for :";
+
+    String KEYSTOREKEYMGR_NULL_ALIAS = "PL00059: KeyStoreKeyManager : Alias is null";
+
+    String KEYSTOREKEYMGR_NULL_KEYSTORE = "PL00055: KeyStoreKeyManager : KeyStore is null";
+
+    String KEYSTOREKEYMGR_NULL_SIGNING_KEYPASS = "PL00057: KeyStoreKeyManager :: Signing Key Pass is null";
+
+    String KEYSTOREKEYMGR_NULL_ENCRYPTION_KEYPASS = "PL00189: KeyStoreKeyManager :: Encryption Key Pass is null";
+
+    String KEYSTOREKEYMGR_KEYSTORE_NOT_LOCATED = "PL00056: KeyStoreKeyManager: Keystore not located:";
+
+    String NOT_EQUAL = "PL00094: Not equal:";
+
+    String NOT_IMPLEMENTED_YET = "PL00082: Not Implemented Yet: ";
+
+    String NOT_SERIALIZABLE = "PL00093: Not Serializable:";
+
+    String NULL_ARGUMENT = "PL00078: Null Parameter:";
+
+    String NULL_ASSERTION = "PL00054: Assertion is null";
+
+    String NULL_ISSUE_INSTANT = "PL00088: Null IssueInstant";
+
+    String NULL_INPUT_STREAM = "PL00060: Input Stream is null";
+
+    String NULL_START_ELEMENT = "PL00068: Parser : Start Element is null";
+
+    String NULL_VALUE = "PL00092: Null Value:";
+
+    String OPTION_NOT_SET = "PL00076: Option not set:";
+
+    String PARSING_ERROR = "PL00074: Parsing Error:";
+
+    String PRINCIPAL_NOT_FOUND = "PL00022: Principal Not Found";
+
+    String PROCESSING_EXCEPTION = "PL00102: Processing Exception:";
+
+    String REQD_ATTRIBUTE = "PL00063: Parser: Required attribute missing: ";
+
+    String RESOURCE_NOT_FOUND = "PL00018: Resource not found:";
+
+    String SAML2STSLM_CONF_FILE_MISSING = "PL00039: SAML2STSLoginModule: Failed to validate assertion: STS configuration file not specified";
+
+    String SAML2STSLM_UNABLE_DECODE_PWD = "PL00047: SAML2STSLoginModule: Unable to decode password:";
+
+    String SERVICE_PROVIDER_CONF_FILE_MISSING = "PL00025: Service Provider:: Configuration File missing:";
+
+    String SERVICE_PROVIDER_NOT_CATALINA_RESPONSE = "PL00026: Response was not of type catalina response";
+
+    String SERVICE_PROVIDER_SERVER_EXCEPTION = "PL00032: Service Provider :: Server Exception";
+
+    String SHOULD_NOT_BE_THE_SAME = "PL00016: Should not be the same:";
+
+    String SIGNING_PROCESS_FAILURE = "PL00100: Signing Process Failure:";
+
+    String STS_CLIENT_PUBLIC_KEY_ERROR = "PL00008: Unable to locate client public key";
+
+    String STS_CONFIGURATION_NOT_SET = "PL00014: Configuration is not set";
+
+    String STS_CONFIGURATION_FILE_PARSING_ERROR = "PL00005: Error parsing the configuration file:";
+
+    String STS_CONFIGURATION_EXCEPTION = "PL00002: Encountered configuration exception:";
+
+    String STS_COMBINED_SECRET_KEY_ERROR = "PL00006: Error generating combined secret key:";
+
+    String STS_EXCEPTION_HANDLING_TOKEN_REQ = "PL00003: Exception in handling token request: ";
+
+    String STS_NO_TOKEN_PROVIDER = "PL00013: No Security Token Provider found in configuration:[";
+
+    String STS_INVALID_TOKEN_REQUEST = "PL00001: Invalid security token request";
+
+    String STS_INVALID_REQUEST_TYPE = "PL00001: Invalid request type: ";
+
+    String STS_PUBLIC_KEY_ERROR = "PL00010: Error obtaining public key for service: ";
+
+    String STS_PUBLIC_KEY_CERT = "PL00012: Error obtaining public key certificate:";
+
+    String STS_RESPONSE_WRITING_ERROR = "PL00004: Error writing response: ";
+
+    String STS_SIGNING_KEYPAIR_ERROR = "PL00011: Error obtaining signing key pair:";
+
+    String STS_UNABLE_TO_CONSTRUCT_KEYMGR = "PL00007: Unable to construct the key manager:";
+
+    String SYSTEM_PROPERTY_MISSING = "PL00087: System Property missing:";
+
+    String TRUST_MANAGER_MISSING = "PL000023: Trust Key Manager Missing";
+
+    String UNABLE_PARSING_NULL_TOKEN = "PL00073: Parser: Unable to parse token request: security token is null";
+
+    String UNABLE_LOCAL_AUTH = "PL00035: Unable to fallback on local auth:";
+
+    String UNKNOWN_END_ELEMENT = "PL00061: Parser: Unknown End Element:";
+
+    String UNKNOWN_OBJECT_TYPE = "PL00089: Unknown Object Type:";
+
+    String UNKNOWN_START_ELEMENT = "PL00064: Parser: Unknown Start Element: ";
+
+    String UNKNOWN_SIG_ALGO = "PL00090: Unknown Signature Algorithm:";
+
+    String UNKNOWN_ENC_ALGO = "PL00097: Unknown Encryption Algorithm:";
+
+    String UNKNOWN_TAG = "PL00062: Parser : Unknown tag:";
+
+    String UNKNOWN_XSI = "PL0065: Parser : Unknown xsi:type=";
+
+    String UNSUPPORTED_TYPE = "PL00069: Parser: Type not supported:";
+
+    String VALIDATION_CHECK_FAILED = "PL00019: Validation check failed";
+
+    String WRITER_INVALID_KEYINFO_NULL_CONTENT = "PL00091: Writer: Invalid KeyInfo object: content cannot be empty";
+
+    String WRITER_NULL_VALUE = "PL00083: Writer: Null Value:";
+
+    String WRITER_SHOULD_START_ELEMENT = "PL00096: Writer: Should have been a StartElement";
+
+    String WRITER_UNKNOWN_TYPE = "PL00081: Writer: Unknown Type:";
+
+    String WRITER_UNSUPPORTED_ATTRIB_VALUE = "PL00084: Writer: Unsupported Attribute Value:";
+
+    String WRONG_TYPE = "PL00095: Wrong type:";
+
+    String SOAP_MESSAGE_DUMP_ERROR = "PL00104: Error while dumping SOAP message:";
+
+    String LOCAL_VALIDATION_SEC_DOMAIN_MUST_BE_SPECIFIED = "PL00105: When using local validation 'localValidationSecurityDomain' must be specified.";
+
+    String COMPRESSION_ENABLED_SAML_CRED = "When compression is enabled, received credential should be SamlCredential, but got ";
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/exceptions/ConfigurationException.java b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/ConfigurationException.java
new file mode 100755
index 0000000..4a377b0
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/ConfigurationException.java
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.exceptions;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * Exception indicating an issue with the configuration
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since May 22, 2009
+ */
+public class ConfigurationException extends GeneralSecurityException {
+    
+    public ConfigurationException() {
+        super();
+    }
+
+    public ConfigurationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public ConfigurationException(String message) {
+        super(message);
+    }
+
+    public ConfigurationException(Throwable cause) {
+        super(cause);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/AssertionExpiredException.java b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/AssertionExpiredException.java
new file mode 100755
index 0000000..746c072
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/AssertionExpiredException.java
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.exceptions.fed;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * Security Exception indicating expiration of SAML2 assertion
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 12, 2008
+ */
+public class AssertionExpiredException extends GeneralSecurityException {
+
+    protected String id;
+
+    public AssertionExpiredException() {
+    }
+
+    public AssertionExpiredException(String message, Throwable cause) {
+    }
+
+    public AssertionExpiredException(String msg) {
+        super(msg);
+    }
+
+    public AssertionExpiredException(Throwable cause) {
+        super(cause);
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/IssueInstantMissingException.java b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/IssueInstantMissingException.java
new file mode 100755
index 0000000..e8cbd56
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/IssueInstantMissingException.java
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.exceptions.fed;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * Exception indicating that the IssueInstant is missing
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jun 3, 2009
+ */
+public class IssueInstantMissingException extends GeneralSecurityException {
+
+    public IssueInstantMissingException() {
+        super();
+    }
+
+    public IssueInstantMissingException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public IssueInstantMissingException(String msg) {
+        super(msg);
+    }
+
+    public IssueInstantMissingException(Throwable cause) {
+        super(cause);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/IssuerNotTrustedException.java b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/IssuerNotTrustedException.java
new file mode 100755
index 0000000..02820ee
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/IssuerNotTrustedException.java
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.exceptions.fed;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * Exception indicating that the issuer is not trusted
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jan 26, 2009
+ */
+public class IssuerNotTrustedException extends GeneralSecurityException {
+
+    public IssuerNotTrustedException() {
+        super();
+    }
+
+    public IssuerNotTrustedException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public IssuerNotTrustedException(String msg) {
+        super(msg);
+    }
+
+    public IssuerNotTrustedException(Throwable cause) {
+        super(cause);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/SignatureValidationException.java b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/SignatureValidationException.java
new file mode 100755
index 0000000..bfafecd
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/SignatureValidationException.java
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.exceptions.fed;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * Indicates the failure of signature validation
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jul 28, 2011
+ */
+public class SignatureValidationException extends GeneralSecurityException {
+
+    public SignatureValidationException() {
+    }
+
+    public SignatureValidationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public SignatureValidationException(String msg) {
+        super(msg);
+    }
+
+    public SignatureValidationException(Throwable cause) {
+        super(cause);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/WSTrustException.java b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/WSTrustException.java
new file mode 100755
index 0000000..937ebb6
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/fed/WSTrustException.java
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.exceptions.fed;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * <p>
+ * Exception used to convey that an error has happened when handling a WS-Trust request message.
+ * </p>
+ *
+ * @author <a href="mailto:sguilhen@redhat.com">Stefan Guilhen</a>
+ */
+public class WSTrustException extends GeneralSecurityException {
+
+    /**
+     * <p>
+     * Creates an instance of {@code WSTrustException} using the specified error message.
+     * </p>
+     *
+     * @param message the error message.
+     */
+    public WSTrustException(String message) {
+        super(message);
+    }
+
+    /**
+     * <p>
+     * Creates an instance of {@code WSTrustException} using the specified error message and cause.
+     * </p>
+     *
+     * @param message the error message.
+     * @param cause a {@code Throwable} representing the cause of the error.
+     */
+    public WSTrustException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * <p>
+     * Creates an instance of {@code WSTrustException} using the specified {@link Throwable}.
+     * </p>
+     *
+     * @param message the error message.
+     */
+    public WSTrustException(Throwable t) {
+        super(t);
+    }
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/exceptions/NotImplementedException.java b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/NotImplementedException.java
new file mode 100755
index 0000000..e49603a
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/NotImplementedException.java
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.keycloak.saml.common.exceptions;
+
+/**
+ * <p>An exception that indicates that something is not ready for use. Usually, this exception is thrown from methods not
+ * fully implemented or tested but available for invocation.</p>
+ *
+ * @author Pedro Igor
+ */
+public class NotImplementedException extends PicketLinkException {
+
+    public NotImplementedException(String message) {
+        super(message);
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/exceptions/ParsingException.java b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/ParsingException.java
new file mode 100755
index 0000000..ea1fa2b
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/ParsingException.java
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.exceptions;
+
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import java.security.GeneralSecurityException;
+
+/**
+ * General Exception indicating parsing exception
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since May 22, 2009
+ */
+public class ParsingException extends GeneralSecurityException {
+
+    private Location location;
+
+    public ParsingException() {
+        super();
+    }
+
+    public ParsingException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public ParsingException(String message) {
+        super(message);
+    }
+
+    public ParsingException(Throwable cause) {
+        super(cause);
+    }
+
+    public ParsingException(XMLStreamException xmle) {
+        super(xmle);
+        location = xmle.getLocation();
+    }
+
+    public Location getLocation() {
+        return location;
+    }
+
+    @Override
+    public String toString() {
+        return "ParsingException [location=" + location + "]" + super.toString();
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/exceptions/PicketLinkException.java b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/PicketLinkException.java
new file mode 100755
index 0000000..799e377
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/PicketLinkException.java
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.exceptions;
+
+/**
+ * <p>Any exception that is raised by the security module extends from this runtime exception class, making it easy for
+ * other modules and extensions to catch all security-related exceptions in a single catch block, if need be.
+ * </p>
+ *
+ * <p>This class is used as the root instead of {@link SecurityException} to avoid confusion and potential conflicts. Eg.: many other
+ * frameworks and products (eg.: JEE containers) relies on the {@link SecurityException} to perform some special handling.</p>
+ */
+public class PicketLinkException extends RuntimeException {
+
+    public PicketLinkException() {
+        super();
+    }
+
+    public PicketLinkException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public PicketLinkException(String message) {
+        super(message);
+    }
+
+    public PicketLinkException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/exceptions/ProcessingException.java b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/ProcessingException.java
new file mode 100755
index 0000000..2b88e2f
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/ProcessingException.java
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.exceptions;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * Exception to indicate a server processing error
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since May 22, 2009
+ */
+public class ProcessingException extends GeneralSecurityException {
+
+    public ProcessingException() {
+        super();
+    }
+
+    public ProcessingException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public ProcessingException(String message) {
+        super(message);
+    }
+
+    public ProcessingException(Throwable cause) {
+        super(cause);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/exceptions/TrustKeyConfigurationException.java b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/TrustKeyConfigurationException.java
new file mode 100755
index 0000000..7f88085
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/TrustKeyConfigurationException.java
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.exceptions;
+
+/**
+ * ConfigurationException in the TrustKeyManager
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since May 22, 2009
+ */
+public class TrustKeyConfigurationException extends ConfigurationException {
+
+    public TrustKeyConfigurationException() {
+        super();
+    }
+
+    public TrustKeyConfigurationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public TrustKeyConfigurationException(String message) {
+        super(message);
+    }
+
+    public TrustKeyConfigurationException(Throwable cause) {
+        super(cause);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/exceptions/TrustKeyProcessingException.java b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/TrustKeyProcessingException.java
new file mode 100755
index 0000000..b900f0e
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/exceptions/TrustKeyProcessingException.java
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.exceptions;
+
+/**
+ * Processing Exception in the trust key manager
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since May 22, 2009
+ */
+public class TrustKeyProcessingException extends ProcessingException {
+
+    public TrustKeyProcessingException() {
+        super();
+    }
+
+    public TrustKeyProcessingException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public TrustKeyProcessingException(String message) {
+        super(message);
+    }
+
+    public TrustKeyProcessingException(Throwable cause) {
+        super(cause);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/parsers/AbstractParser.java b/saml-core/src/main/java/org/keycloak/saml/common/parsers/AbstractParser.java
new file mode 100755
index 0000000..dc25f17
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/parsers/AbstractParser.java
@@ -0,0 +1,141 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.parsers;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.common.util.SystemPropertiesUtil;
+
+import javax.xml.stream.EventFilter;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.XMLEvent;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Base class for parsers
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Oct 12, 2010
+ */
+public abstract class AbstractParser implements ParserNamespaceSupport {
+
+    protected static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * Get the JAXP {@link XMLInputFactory}
+     *
+     * @return
+     */
+    protected XMLInputFactory getXMLInputFactory() {
+        boolean tccl_jaxp = SystemPropertiesUtil.getSystemProperty(GeneralConstants.TCCL_JAXP, "false")
+                .equalsIgnoreCase("true");
+        ClassLoader prevTCCL = getTCCL();
+        try {
+            if (tccl_jaxp) {
+                setTCCL(getClass().getClassLoader());
+            }
+            return XMLInputFactory.newInstance();
+        } finally {
+            if (tccl_jaxp) {
+                setTCCL(prevTCCL);
+            }
+        }
+    }
+
+    /**
+     * Parse an InputStream for payload
+     *
+     * @param configStream
+     *
+     * @return
+     *
+     * @throws {@link IllegalArgumentException}
+     * @throws {@link IllegalArgumentException} when the configStream is null
+     */
+    public Object parse(InputStream configStream) throws ParsingException {
+        XMLEventReader xmlEventReader = createEventReader(configStream);
+        return parse(xmlEventReader);
+    }
+
+    public XMLEventReader createEventReader(InputStream configStream) throws ParsingException {
+        if (configStream == null)
+            throw logger.nullArgumentError("InputStream");
+
+        XMLInputFactory xmlInputFactory = getXMLInputFactory();
+
+        XMLEventReader xmlEventReader = StaxParserUtil.getXMLEventReader(configStream);
+
+        try {
+            xmlEventReader = xmlInputFactory.createFilteredReader(xmlEventReader, new EventFilter() {
+                public boolean accept(XMLEvent xmlEvent) {
+                    // We are going to disregard characters that are new line and whitespace
+                    if (xmlEvent.isCharacters()) {
+                        Characters chars = xmlEvent.asCharacters();
+                        String data = chars.getData();
+                        data = valid(data) ? data.trim() : null;
+                        return valid(data);
+                    } else {
+                        return xmlEvent.isStartElement() || xmlEvent.isEndElement();
+                    }
+                }
+
+                private boolean valid(String str) {
+                    return str != null && str.length() > 0;
+                }
+            });
+        } catch (XMLStreamException e) {
+            throw logger.parserException(e);
+        }
+
+        return xmlEventReader;
+    }
+
+    private ClassLoader getTCCL() {
+        if (System.getSecurityManager() != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
+                    return Thread.currentThread().getContextClassLoader();
+                }
+            });
+        } else {
+            return Thread.currentThread().getContextClassLoader();
+        }
+    }
+
+    private void setTCCL(final ClassLoader paramCl) {
+        if (System.getSecurityManager() != null) {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    Thread.currentThread().setContextClassLoader(paramCl);
+                    return null;
+                }
+            });
+        } else {
+            Thread.currentThread().setContextClassLoader(paramCl);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/parsers/ParserNamespaceSupport.java b/saml-core/src/main/java/org/keycloak/saml/common/parsers/ParserNamespaceSupport.java
new file mode 100755
index 0000000..197143c
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/parsers/ParserNamespaceSupport.java
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.parsers;
+
+import org.keycloak.saml.common.exceptions.ParsingException;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+
+/**
+ * <p>
+ * Interface to indicate the parser supports a particular namespace.
+ * </p>
+ *
+ * <p>
+ * This class needs to be moved to the security common project.
+ * </p>
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Feb 5, 2010
+ */
+public interface ParserNamespaceSupport {
+    /**
+     * Parse the event stream
+     *
+     * @param xmlEventReader
+     * @return
+     * @throws ParsingException
+     */
+    Object parse(XMLEventReader xmlEventReader) throws ParsingException;
+
+    /**
+     * Returns whether the parser supports parsing a particular namespace
+     *
+     * @param qname
+     * @return
+     */
+    boolean supports(QName qname);
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/PicketLinkLoggerFactory.java b/saml-core/src/main/java/org/keycloak/saml/common/PicketLinkLoggerFactory.java
new file mode 100755
index 0000000..6461eaa
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/PicketLinkLoggerFactory.java
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common;
+
+/**
+ * <p> Factory class to create {@link PicketLinkLogger} instances. </p> <p> The logger instances are created based on
+ * the following patterns: <br/> <ul> <li>Tries to load a class with the same full qualified name of {@link
+ * PicketLinkLogger} plus the "Impl" suffix;</li> <li>If no class is found fallback to the {@link
+ * DefaultPicketLinkLogger} as the default logger implementation.</li> </ul> </p>
+ *
+ * @author <a href="mailto:psilva@redhat.com">Pedro Silva</a>
+ */
+public final class PicketLinkLoggerFactory {
+
+    private static PicketLinkLogger LOGGER;
+
+    static {
+        try {
+            LOGGER = (PicketLinkLogger) Class.forName(PicketLinkLogger.class.getName() + "Impl").newInstance();
+        } catch (Exception e) {
+            // if no implementation is found uses the default implementation.
+            LOGGER = new DefaultPicketLinkLogger();
+        }
+
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.usingLoggerImplementation(LOGGER.getClass().getName());
+        }
+    }
+
+    /**
+     * <p>Returns a {@link PicketLinkLogger} instance.</p>
+     *
+     * @return
+     */
+    public static PicketLinkLogger getLogger() {
+        return LOGGER;
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/util/SecurityActions.java b/saml-core/src/main/java/org/keycloak/saml/common/util/SecurityActions.java
new file mode 100755
index 0000000..24bd70b
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/util/SecurityActions.java
@@ -0,0 +1,221 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.util;
+
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 9, 2008
+ */
+class SecurityActions {
+
+    /**
+     * <p> Loads a {@link Class} using the <code>fullQualifiedName</code> supplied. This method tries first to load from
+     * the specified {@link Class}, if not found it will try to load from using TCL. </p>
+     *
+     * @param theClass
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final Class<?> theClass, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    ClassLoader classLoader = theClass.getClassLoader();
+
+                    Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+                    if (clazz == null) {
+                        classLoader = Thread.currentThread().getContextClassLoader();
+                        clazz = loadClass(classLoader, fullQualifiedName);
+                    }
+                    return clazz;
+                }
+            });
+        } else {
+            ClassLoader classLoader = theClass.getClassLoader();
+
+            Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+            if (clazz == null) {
+                classLoader = Thread.currentThread().getContextClassLoader();
+                clazz = loadClass(classLoader, fullQualifiedName);
+            }
+            return clazz;
+        }
+    }
+
+    /**
+     * <p> Loads a class from the specified {@link ClassLoader} using the <code>fullQualifiedName</code> supplied. </p>
+     *
+     * @param classLoader
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final ClassLoader classLoader, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    try {
+                        return classLoader.loadClass(fullQualifiedName);
+                    } catch (ClassNotFoundException e) {
+                    }
+                    return null;
+                }
+            });
+        } else {
+            try {
+                return classLoader.loadClass(fullQualifiedName);
+            } catch (ClassNotFoundException e) {
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Load a resource based on the passed {@link Class} classloader. Failing which try with the Thread Context CL
+     *
+     * @param clazz
+     * @param resourceName
+     *
+     * @return
+     */
+    static URL loadResource(final Class<?> clazz, final String resourceName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<URL>() {
+                public URL run() {
+                    URL url = null;
+                    ClassLoader clazzLoader = clazz.getClassLoader();
+                    url = clazzLoader.getResource(resourceName);
+
+                    if (url == null) {
+                        clazzLoader = Thread.currentThread().getContextClassLoader();
+                        url = clazzLoader.getResource(resourceName);
+                    }
+
+                    return url;
+                }
+            });
+        } else {
+            URL url = null;
+            ClassLoader clazzLoader = clazz.getClassLoader();
+            url = clazzLoader.getResource(resourceName);
+
+            if (url == null) {
+                clazzLoader = Thread.currentThread().getContextClassLoader();
+                url = clazzLoader.getResource(resourceName);
+            }
+
+            return url;
+        }
+    }
+
+    /**
+     * Set the system property
+     *
+     * @param key
+     * @param defaultValue
+     *
+     * @return
+     */
+    static void setSystemProperty(final String key, final String value) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                public Object run() {
+                    System.setProperty(key, value);
+                    return null;
+                }
+            });
+        } else {
+            System.setProperty(key, value);
+        }
+    }
+
+    /**
+     * <p>Returns a system property value using the specified <code>key</code>. If not found the
+     * <code>defaultValue</code> will be returned.</p>
+     *
+     * @param key
+     * @param defaultValue
+     *
+     * @return
+     */
+    static String getSystemProperty(final String key, final String defaultValue) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty(key, defaultValue);
+                }
+            });
+        } else {
+            return System.getProperty(key, defaultValue);
+        }
+    }
+
+    /**
+     * Get the Thread Context ClassLoader
+     *
+     * @return
+     */
+    static ClassLoader getTCCL() {
+        if (System.getSecurityManager() != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
+                    return Thread.currentThread().getContextClassLoader();
+                }
+            });
+        } else {
+            return Thread.currentThread().getContextClassLoader();
+        }
+    }
+
+    /**
+     * Set the Thread Context ClassLoader
+     *
+     * @param paramCl
+     */
+    static void setTCCL(final ClassLoader paramCl) {
+        if (System.getSecurityManager() != null) {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    Thread.currentThread().setContextClassLoader(paramCl);
+                    return null;
+                }
+            });
+        } else {
+
+            Thread.currentThread().setContextClassLoader(paramCl);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/util/StaxUtil.java b/saml-core/src/main/java/org/keycloak/saml/common/util/StaxUtil.java
new file mode 100755
index 0000000..be4ef43
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/util/StaxUtil.java
@@ -0,0 +1,447 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.util;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Result;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.Stack;
+
+/**
+ * Utility class that deals with StAX
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Oct 19, 2010
+ */
+public class StaxUtil {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    private static ThreadLocal<Stack<String>> registeredNSStack = new ThreadLocal<Stack<String>>();
+
+    /**
+     * Flush the stream writer
+     *
+     * @param writer
+     *
+     * @throws org.keycloak.saml.common.exceptions.ProcessingException
+     */
+    public static void flush(XMLStreamWriter writer) throws ProcessingException {
+        try {
+            writer.flush();
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * Get an {@code XMLEventWriter}
+     *
+     * @param outStream
+     *
+     * @return
+     *
+     * @throws ProcessingException
+     */
+    public static XMLEventWriter getXMLEventWriter(final OutputStream outStream) throws ProcessingException {
+        XMLOutputFactory xmlOutputFactory = getXMLOutputFactory();
+        try {
+            return xmlOutputFactory.createXMLEventWriter(outStream, "UTF-8");
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * Get an {@code XMLStreamWriter}
+     *
+     * @param outStream
+     *
+     * @return
+     *
+     * @throws ProcessingException
+     */
+    public static XMLStreamWriter getXMLStreamWriter(final OutputStream outStream) throws ProcessingException {
+        XMLOutputFactory xmlOutputFactory = getXMLOutputFactory();
+        try {
+            return xmlOutputFactory.createXMLStreamWriter(outStream, "UTF-8");
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * Get an {@code XMLStreamWriter}
+     *
+     * @param writer {@code Writer}
+     *
+     * @return
+     *
+     * @throws ProcessingException
+     */
+    public static XMLStreamWriter getXMLStreamWriter(final Writer writer) throws ProcessingException {
+        XMLOutputFactory xmlOutputFactory = getXMLOutputFactory();
+        try {
+            return xmlOutputFactory.createXMLStreamWriter(writer);
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    public static XMLStreamWriter getXMLStreamWriter(final Result result) throws ProcessingException {
+        XMLOutputFactory factory = getXMLOutputFactory();
+        try {
+            return factory.createXMLStreamWriter(result);
+        } catch (XMLStreamException xe) {
+            throw logger.processingError(xe);
+        }
+    }
+
+    /**
+     * Set a prefix
+     *
+     * @param writer
+     * @param prefix
+     * @param nsURI
+     *
+     * @throws ProcessingException
+     */
+    public static void setPrefix(XMLStreamWriter writer, String prefix, String nsURI) throws ProcessingException {
+        try {
+            writer.setPrefix(prefix, nsURI);
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * Write an attribute
+     *
+     * @param writer
+     * @param attributeName QName of the attribute
+     * @param attributeValue
+     *
+     * @throws ProcessingException
+     */
+    public static void writeAttribute(XMLStreamWriter writer, String attributeName, QName attributeValue)
+            throws ProcessingException {
+        writeAttribute(writer, attributeName, attributeValue.toString());
+    }
+
+    /**
+     * Write an attribute
+     *
+     * @param writer
+     * @param attributeName QName of the attribute
+     * @param attributeValue
+     *
+     * @throws ProcessingException
+     */
+    public static void writeAttribute(XMLStreamWriter writer, QName attributeName, String attributeValue)
+            throws ProcessingException {
+        try {
+            writer.writeAttribute(attributeName.getPrefix(), attributeName.getNamespaceURI(), attributeName.getLocalPart(),
+                    attributeValue);
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * Write an xml attribute
+     *
+     * @param writer
+     * @param localName localpart
+     * @param value value of the attribute
+     *
+     * @throws ProcessingException
+     */
+    public static void writeAttribute(XMLStreamWriter writer, String localName, String value) throws ProcessingException {
+        try {
+            writer.writeAttribute(localName, value);
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * Write an xml attribute
+     *
+     * @param writer
+     * @param localName localpart
+     * @param type typically xsi:type
+     * @param value value of the attribute
+     *
+     * @throws ProcessingException
+     */
+    public static void writeAttribute(XMLStreamWriter writer, String localName, String type, String value)
+            throws ProcessingException {
+        try {
+            writer.writeAttribute(localName, type, value);
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * Write an xml attribute
+     *
+     * @param writer
+     * @param prefix prefix for the attribute
+     * @param localName localpart
+     * @param type typically xsi:type
+     * @param value value of the attribute
+     *
+     * @throws ProcessingException
+     */
+    public static void writeAttribute(XMLStreamWriter writer, String prefix, String localName, String type, String value)
+            throws ProcessingException {
+        try {
+            writer.writeAttribute(prefix, localName, type, value);
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * Write a string as text node
+     *
+     * @param writer
+     * @param value
+     *
+     * @throws ProcessingException
+     */
+    public static void writeCharacters(XMLStreamWriter writer, String value) throws ProcessingException {
+        try {
+            writer.writeCharacters(value);
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * Write a string as text node
+     *
+     * @param writer
+     * @param value
+     *
+     * @throws ProcessingException
+     */
+    public static void writeCData(XMLStreamWriter writer, String value) throws ProcessingException {
+        try {
+            writer.writeCData(value);
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * Write the default namespace
+     *
+     * @param writer
+     * @param ns
+     *
+     * @throws ProcessingException
+     */
+    public static void writeDefaultNameSpace(XMLStreamWriter writer, String ns) throws ProcessingException {
+        try {
+            writer.writeDefaultNamespace(ns);
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * Write a DOM Node to the stream
+     *
+     * @param writer
+     * @param node
+     *
+     * @throws ProcessingException
+     */
+    public static void writeDOMNode(XMLStreamWriter writer, Node node) throws ProcessingException {
+        try {
+            short nodeType = node.getNodeType();
+
+            switch (nodeType) {
+                case Node.ELEMENT_NODE:
+                    writeDOMElement(writer, (Element) node);
+                    break;
+                case Node.TEXT_NODE:
+                    writer.writeCharacters(node.getNodeValue());
+                    break;
+                case Node.COMMENT_NODE:
+                    writer.writeComment(node.getNodeValue());
+                    break;
+                case Node.CDATA_SECTION_NODE:
+                    writer.writeCData(node.getNodeValue());
+                    break;
+                default:
+                    // Don't care
+            }
+        } catch (DOMException e) {
+            throw logger.processingError(e);
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * Write DOM Element to the stream
+     *
+     * @param writer
+     * @param domElement
+     *
+     * @throws ProcessingException
+     */
+    public static void writeDOMElement(XMLStreamWriter writer, Element domElement) throws ProcessingException {
+        if (registeredNSStack.get() == null) {
+            registeredNSStack.set(new Stack<String>());
+        }
+        String domElementPrefix = domElement.getPrefix();
+
+        if (domElementPrefix == null) {
+            domElementPrefix = "";
+        }
+
+        String domElementNS = domElement.getNamespaceURI();
+        if (domElementNS == null) {
+            domElementNS = "";
+        }
+
+        writeStartElement(writer, domElementPrefix, domElement.getLocalName(), domElementNS);
+
+        // Should we register namespace
+        if (domElementPrefix != "" && !registeredNSStack.get().contains(domElementNS)) {
+            // writeNameSpace(writer, domElementPrefix, domElementNS );
+            registeredNSStack.get().push(domElementNS);
+        } else if (domElementPrefix == "" && domElementNS != null) {
+            writeNameSpace(writer, "xmlns", domElementNS);
+        }
+
+        // Deal with Attributes
+        NamedNodeMap attrs = domElement.getAttributes();
+        for (int i = 0, len = attrs.getLength(); i < len; ++i) {
+            Attr attr = (Attr) attrs.item(i);
+            String attributePrefix = attr.getPrefix();
+            String attribLocalName = attr.getLocalName();
+            String attribValue = attr.getValue();
+
+            if (attributePrefix == null || attributePrefix.length() == 0) {
+                if (!("xmlns".equals(attribLocalName))) {
+                    writeAttribute(writer, attribLocalName, attribValue);
+                }
+            } else {
+                if ("xmlns".equals(attributePrefix)) {
+                    writeNameSpace(writer, attribLocalName, attribValue);
+                } else {
+                    writeAttribute(writer, new QName(attr.getNamespaceURI(), attribLocalName, attributePrefix), attribValue);
+                }
+            }
+        }
+
+        for (Node child = domElement.getFirstChild(); child != null; child = child.getNextSibling()) {
+            writeDOMNode(writer, child);
+        }
+
+        writeEndElement(writer);
+    }
+
+    /**
+     * Write a namespace
+     *
+     * @param writer
+     * @param prefix prefix
+     * @param ns Namespace URI
+     *
+     * @throws ProcessingException
+     */
+    public static void writeNameSpace(XMLStreamWriter writer, String prefix, String ns) throws ProcessingException {
+        try {
+            writer.writeNamespace(prefix, ns);
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * Write a start element
+     *
+     * @param writer
+     * @param prefix
+     * @param localPart
+     * @param ns
+     *
+     * @throws ProcessingException
+     */
+    public static void writeStartElement(XMLStreamWriter writer, String prefix, String localPart, String ns)
+            throws ProcessingException {
+        try {
+            writer.writeStartElement(prefix, localPart, ns);
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    /**
+     * <p> Write an end element. The stream writer keeps track of which start element needs to be closed with an end
+     * tag. </p>
+     *
+     * @param writer
+     *
+     * @throws ProcessingException
+     */
+    public static void writeEndElement(XMLStreamWriter writer) throws ProcessingException {
+        try {
+            writer.writeEndElement();
+        } catch (XMLStreamException e) {
+            throw logger.processingError(e);
+        }
+    }
+
+    private static XMLOutputFactory getXMLOutputFactory() {
+        boolean tccl_jaxp = SystemPropertiesUtil.getSystemProperty(GeneralConstants.TCCL_JAXP, "false")
+                .equalsIgnoreCase("true");
+        ClassLoader prevTCCL = SecurityActions.getTCCL();
+        try {
+            if (tccl_jaxp) {
+                SecurityActions.setTCCL(StaxUtil.class.getClassLoader());
+            }
+            return XMLOutputFactory.newInstance();
+        } finally {
+            if (tccl_jaxp) {
+                SecurityActions.setTCCL(prevTCCL);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/util/StringUtil.java b/saml-core/src/main/java/org/keycloak/saml/common/util/StringUtil.java
new file mode 100755
index 0000000..3db64c2
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/util/StringUtil.java
@@ -0,0 +1,199 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.util;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.PicketLinkCommonConstants;
+
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Utility dealing with Strings
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Oct 21, 2009
+ */
+public class StringUtil {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * Check whether the passed string is null or empty
+     *
+     * @param str
+     *
+     * @return
+     */
+    public static boolean isNotNull(String str) {
+        return str != null && !"".equals(str.trim());
+    }
+
+    /**
+     * Check whether the string is null or empty
+     *
+     * @param str
+     *
+     * @return
+     */
+    public static boolean isNullOrEmpty(String str) {
+        return str == null || str.isEmpty();
+    }
+
+    /**
+     * <p>
+     * Get the system property value if the string is of the format ${sysproperty}
+     * </p>
+     * <p>
+     * You can insert default value when the system property is not set, by separating it at the beginning with ::
+     * </p>
+     * <p>
+     * <b>Examples:</b>
+     * </p>
+     *
+     * <p>
+     * ${idp} should resolve to a value if the system property "idp" is set.
+     * </p>
+     * <p>
+     * ${idp::http://localhost:8080} will resolve to http://localhost:8080 if the system property "idp" is not set.
+     * </p>
+     *
+     * @param str
+     *
+     * @return
+     */
+    public static String getSystemPropertyAsString(String str) {
+        if (str == null)
+            throw logger.nullArgumentError("str");
+        if (str.contains("${")) {
+            Pattern pattern = Pattern.compile("\\$\\{([^}]+)}");
+            Matcher matcher = pattern.matcher(str);
+
+            StringBuffer buffer = new StringBuffer();
+            String sysPropertyValue = null;
+
+            while (matcher.find()) {
+                String subString = matcher.group(1);
+                String defaultValue = "";
+
+                // Look for default value
+                if (subString.contains("::")) {
+                    int index = subString.indexOf("::");
+                    defaultValue = subString.substring(index + 2);
+                    subString = subString.substring(0, index);
+                }
+                sysPropertyValue = SecurityActions.getSystemProperty(subString, defaultValue);
+                if (sysPropertyValue.isEmpty()) {
+                    throw logger.systemPropertyMissingError(matcher.group(1));
+                }else{
+                    // sanitize the value before we use append-and-replace
+                    sysPropertyValue = Matcher.quoteReplacement(sysPropertyValue);
+                }
+                matcher.appendReplacement(buffer, sysPropertyValue);
+            }
+
+            matcher.appendTail(buffer);
+            str = buffer.toString();
+        }
+        return str;
+    }
+
+    /**
+     * Match two strings else throw a {@link RuntimeException}
+     *
+     * @param first
+     * @param second
+     */
+    public static void match(String first, String second) {
+        if (first.equals(second) == false)
+            throw logger.notEqualError(first, second);
+    }
+
+    /**
+     * Given a comma separated string, get the tokens as a {@link List}
+     *
+     * @param str
+     *
+     * @return
+     */
+    public static List<String> tokenize(String str) {
+        return tokenize(str, ",");
+    }
+
+    /**
+     * Given a delimited string, get the tokens as a {@link List}
+     *
+     * @param str
+     * @param delimiter the delimiter
+     *
+     * @return
+     */
+    public static List<String> tokenize(String str, String delimiter) {
+        List<String> list = new ArrayList<String>();
+        StringTokenizer tokenizer = new StringTokenizer(str, delimiter);
+        while (tokenizer.hasMoreTokens()) {
+            list.add(tokenizer.nextToken());
+        }
+        return list;
+    }
+
+    /**
+     * Given a string that is comma delimited and contains key-value pairs
+     *
+     * @param keyValuePairString
+     *
+     * @return
+     */
+    public static Map<String, String> tokenizeKeyValuePair(String keyValuePairString) {
+        Map<String, String> map = new HashMap<String, String>();
+
+        List<String> tokens = tokenize(keyValuePairString);
+        for (String token : tokens) {
+            int location = token.indexOf('=');
+            map.put(token.substring(0, location), token.substring(location + 1));
+        }
+        return map;
+    }
+
+    public static String[] split(String toSplit, String delimiter) {
+        if (delimiter.length() != 1) {
+            throw new IllegalArgumentException("Delimiter can only be one character in length");
+        }
+
+        int offset = toSplit.indexOf(delimiter);
+
+        if (offset < 0) {
+            return null;
+        }
+
+        String beforeDelimiter = toSplit.substring(0, offset);
+        String afterDelimiter = toSplit.substring(offset + 1);
+
+        return new String[]{beforeDelimiter, afterDelimiter};
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/util/SystemPropertiesUtil.java b/saml-core/src/main/java/org/keycloak/saml/common/util/SystemPropertiesUtil.java
new file mode 100755
index 0000000..28dd35c
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/common/util/SystemPropertiesUtil.java
@@ -0,0 +1,64 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.common.util;
+
+import javax.xml.XMLConstants;
+
+/**
+ * Utility dealing with the system properties at the JVM level for PicketLink
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jul 1, 2011
+ */
+public class SystemPropertiesUtil {
+    static {
+        // XML Signature
+        String xmlSec = "org.apache.xml.security.ignoreLineBreaks";
+        if (StringUtil.isNullOrEmpty(SecurityActions.getSystemProperty(xmlSec, ""))) {
+            SecurityActions.setSystemProperty(xmlSec, "true");
+        }
+
+        // For JAXP Validation
+        String schemaFactoryProperty = "javax.xml.validation.SchemaFactory:" + XMLConstants.W3C_XML_SCHEMA_NS_URI;
+        if (StringUtil.isNullOrEmpty(SecurityActions.getSystemProperty(schemaFactoryProperty, ""))) {
+            SecurityActions.setSystemProperty(schemaFactoryProperty, "org.apache.xerces.jaxp.validation.XMLSchemaFactory");
+        }
+
+        // For the XACML Engine
+        String xacmlValidation = "org.jboss.security.xacml.schema.validation";
+        if (StringUtil.isNullOrEmpty(SecurityActions.getSystemProperty(xacmlValidation, ""))) {
+            SecurityActions.setSystemProperty(xacmlValidation, "false");
+        }
+    };
+
+    /**
+     * No-op call such that the default system properties are set
+     */
+    public static void ensure() {
+    }
+
+    /**
+     * Get the System Property
+     * @param key key of the system property
+     * @param defaultValue default value to be returned if the system property is not set
+     * @return
+     */
+    public static String getSystemProperty(final String key, final String defaultValue){
+        return SecurityActions.getSystemProperty(key,defaultValue);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/request/SAML2Request.java b/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/request/SAML2Request.java
new file mode 100755
index 0000000..906d908
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/request/SAML2Request.java
@@ -0,0 +1,336 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.api.saml.v2.request;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.util.DocumentUtil;
+import org.keycloak.saml.common.util.StaxUtil;
+import org.keycloak.dom.saml.v2.SAML2Object;
+import org.keycloak.saml.processing.core.parsers.saml.SAMLParser;
+import org.keycloak.saml.processing.core.saml.v2.common.IDGenerator;
+import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.saml.processing.core.saml.v2.writers.SAMLRequestWriter;
+import org.keycloak.saml.processing.core.saml.v2.writers.SAMLResponseWriter;
+import org.keycloak.saml.processing.core.util.JAXPValidationUtil;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
+import org.keycloak.dom.saml.v2.protocol.LogoutRequestType;
+import org.keycloak.dom.saml.v2.protocol.NameIDPolicyType;
+import org.keycloak.dom.saml.v2.protocol.RequestAbstractType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.w3c.dom.Document;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.net.URI;
+import java.net.URL;
+
+/**
+ * API for SAML2 Request
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jan 5, 2009
+ */
+public class SAML2Request {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    private SAMLDocumentHolder samlDocumentHolder = null;
+
+    private String nameIDFormat = JBossSAMLURIConstants.NAMEID_FORMAT_TRANSIENT.get();
+
+    /**
+     * Set the NameIDFormat
+     *
+     * @param nameIDFormat
+     */
+    public void setNameIDFormat(String nameIDFormat) {
+        this.nameIDFormat = nameIDFormat;
+    }
+
+    /**
+     * Create an authentication request
+     *
+     * @param id
+     * @param assertionConsumerURL
+     * @param destination
+     * @param issuerValue
+     *
+     * @return
+     *
+     * @throws ConfigurationException
+     */
+    public AuthnRequestType createAuthnRequestType(String id, String assertionConsumerURL, String destination,
+                                                   String issuerValue) throws ConfigurationException {
+        XMLGregorianCalendar issueInstant = XMLTimeUtil.getIssueInstant();
+
+        AuthnRequestType authnRequest = new AuthnRequestType(id, issueInstant);
+        authnRequest.setAssertionConsumerServiceURL(URI.create(assertionConsumerURL));
+        authnRequest.setProtocolBinding(URI.create(JBossSAMLConstants.HTTP_POST_BINDING.get()));
+        if (destination != null) {
+            authnRequest.setDestination(URI.create(destination));
+        }
+
+        // Create an issuer
+        NameIDType issuer = new NameIDType();
+        issuer.setValue(issuerValue);
+
+        authnRequest.setIssuer(issuer);
+
+        // Create a default NameIDPolicy
+        NameIDPolicyType nameIDPolicy = new NameIDPolicyType();
+        nameIDPolicy.setAllowCreate(Boolean.TRUE);
+        nameIDPolicy.setFormat(URI.create(this.nameIDFormat));
+
+        authnRequest.setNameIDPolicy(nameIDPolicy);
+
+        return authnRequest;
+    }
+
+    /**
+     * Get AuthnRequestType from a file
+     *
+     * @param fileName file with the serialized AuthnRequestType
+     *
+     * @return AuthnRequestType
+     *
+     * @throws ParsingException
+     * @throws ProcessingException
+     * @throws ConfigurationException
+     * @throws IllegalArgumentException if the input fileName is null IllegalStateException if the InputStream from the
+     * fileName
+     * is null
+     */
+    public AuthnRequestType getAuthnRequestType(String fileName) throws ConfigurationException, ProcessingException,
+            ParsingException {
+        if (fileName == null)
+            throw logger.nullArgumentError("fileName");
+        URL resourceURL = SecurityActions.loadResource(getClass(), fileName);
+        if (resourceURL == null)
+            throw logger.resourceNotFound(fileName);
+
+        InputStream is = null;
+        try {
+            is = resourceURL.openStream();
+        } catch (IOException e) {
+            throw logger.processingError(e);
+        }
+        return getAuthnRequestType(is);
+    }
+
+    /**
+     * Get the Underlying SAML2Object from the input stream
+     *
+     * @param is
+     *
+     * @return
+     *
+     * @throws IOException
+     * @throws ParsingException
+     */
+    public SAML2Object getSAML2ObjectFromStream(InputStream is) throws ConfigurationException, ParsingException,
+            ProcessingException {
+        if (is == null)
+            throw logger.nullArgumentError("InputStream");
+
+        Document samlDocument = DocumentUtil.getDocument(is);
+
+        SAMLParser samlParser = new SAMLParser();
+        JAXPValidationUtil.checkSchemaValidation(samlDocument);
+        SAML2Object requestType = (SAML2Object) samlParser.parse(DocumentUtil.getNodeAsStream(samlDocument));
+
+        samlDocumentHolder = new SAMLDocumentHolder(requestType, samlDocument);
+        return requestType;
+    }
+
+    /**
+     * Get a Request Type from Input Stream
+     *
+     * @param is
+     *
+     * @return
+     *
+     * @throws ProcessingException
+     * @throws ConfigurationException
+     * @throws
+     * @throws IllegalArgumentException inputstream is null
+     */
+    public RequestAbstractType getRequestType(InputStream is) throws ParsingException, ConfigurationException,
+            ProcessingException {
+        if (is == null)
+            throw logger.nullArgumentError("InputStream");
+
+        Document samlDocument = DocumentUtil.getDocument(is);
+
+        SAMLParser samlParser = new SAMLParser();
+        JAXPValidationUtil.checkSchemaValidation(samlDocument);
+        RequestAbstractType requestType = (RequestAbstractType) samlParser.parse(DocumentUtil.getNodeAsStream(samlDocument));
+
+        samlDocumentHolder = new SAMLDocumentHolder(requestType, samlDocument);
+        return requestType;
+    }
+
+    /**
+     * Get the AuthnRequestType from an input stream
+     *
+     * @param is Inputstream containing the AuthnRequest
+     *
+     * @return
+     *
+     * @throws ParsingException
+     * @throws ProcessingException
+     * @throws ConfigurationException
+     * @throws IllegalArgumentException inputstream is null
+     */
+    public AuthnRequestType getAuthnRequestType(InputStream is) throws ConfigurationException, ProcessingException,
+            ParsingException {
+        if (is == null)
+            throw logger.nullArgumentError("InputStream");
+
+        Document samlDocument = DocumentUtil.getDocument(is);
+
+        SAMLParser samlParser = new SAMLParser();
+        JAXPValidationUtil.checkSchemaValidation(samlDocument);
+
+        AuthnRequestType requestType = (AuthnRequestType) samlParser.parse(DocumentUtil.getNodeAsStream(samlDocument));
+        samlDocumentHolder = new SAMLDocumentHolder(requestType, samlDocument);
+        return requestType;
+    }
+
+    /**
+     * Get the parsed {@code SAMLDocumentHolder}
+     *
+     * @return
+     */
+    public SAMLDocumentHolder getSamlDocumentHolder() {
+        return samlDocumentHolder;
+    }
+
+    /**
+     * Create a Logout Request
+     *
+     * @param issuer
+     *
+     * @return
+     *
+     * @throws ConfigurationException
+     */
+    public LogoutRequestType createLogoutRequest(String issuer) throws ConfigurationException {
+        LogoutRequestType lrt = new LogoutRequestType(IDGenerator.create("ID_"), XMLTimeUtil.getIssueInstant());
+
+        // Create an issuer
+        NameIDType issuerNameID = new NameIDType();
+        issuerNameID.setValue(issuer);
+
+        lrt.setIssuer(issuerNameID);
+
+        return lrt;
+    }
+
+    /**
+     * Return the DOM object
+     *
+     * @param rat
+     *
+     * @return
+     *
+     * @throws ProcessingException
+     * @throws ParsingException
+     * @throws ConfigurationException
+     */
+    public Document convert(RequestAbstractType rat) throws ProcessingException, ConfigurationException, ParsingException {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+        SAMLRequestWriter writer = new SAMLRequestWriter(StaxUtil.getXMLStreamWriter(bos));
+        if (rat instanceof AuthnRequestType) {
+            writer.write((AuthnRequestType) rat);
+        } else if (rat instanceof LogoutRequestType) {
+            writer.write((LogoutRequestType) rat);
+        }
+
+        return DocumentUtil.getDocument(new String(bos.toByteArray()));
+    }
+
+    /**
+     * Convert a SAML2 Response into a Document
+     *
+     * @param responseType
+     *
+     * @return
+     *
+     * @throws ProcessingException
+     * @throws ParsingException
+     * @throws ConfigurationException
+     */
+    public Document convert(ResponseType responseType) throws ProcessingException, ParsingException, ConfigurationException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SAMLResponseWriter writer = new SAMLResponseWriter(StaxUtil.getXMLStreamWriter(baos));
+        writer.write(responseType);
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        return DocumentUtil.getDocument(bis);
+    }
+
+    /**
+     * Marshall the AuthnRequestType to an output stream
+     *
+     * @param requestType
+     * @param os
+     *
+     * @throws ProcessingException
+     */
+    public void marshall(RequestAbstractType requestType, OutputStream os) throws ProcessingException {
+        SAMLRequestWriter samlRequestWriter = new SAMLRequestWriter(StaxUtil.getXMLStreamWriter(os));
+        if (requestType instanceof AuthnRequestType) {
+            samlRequestWriter.write((AuthnRequestType) requestType);
+        } else if (requestType instanceof LogoutRequestType) {
+            samlRequestWriter.write((LogoutRequestType) requestType);
+        } else
+            throw logger.unsupportedType(requestType.getClass().getName());
+    }
+
+    /**
+     * Marshall the AuthnRequestType to a writer
+     *
+     * @param requestType
+     * @param writer
+     *
+     * @throws ProcessingException
+     */
+    public void marshall(RequestAbstractType requestType, Writer writer) throws ProcessingException {
+        SAMLRequestWriter samlRequestWriter = new SAMLRequestWriter(StaxUtil.getXMLStreamWriter(writer));
+        if (requestType instanceof AuthnRequestType) {
+            samlRequestWriter.write((AuthnRequestType) requestType);
+        } else if (requestType instanceof LogoutRequestType) {
+            samlRequestWriter.write((LogoutRequestType) requestType);
+        } else
+            throw logger.unsupportedType(requestType.getClass().getName());
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/request/SecurityActions.java b/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/request/SecurityActions.java
new file mode 100755
index 0000000..b384af8
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/request/SecurityActions.java
@@ -0,0 +1,166 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.api.saml.v2.request;
+
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 9, 2008
+ */
+class SecurityActions {
+
+    /**
+     * <p>
+     * Loads a {@link Class} using the <code>fullQualifiedName</code> supplied. This method tries first to load from
+     * the
+     * specified {@link Class}, if not found it will try to load from using TCL.
+     * </p>
+     *
+     * @param theClass
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final Class<?> theClass, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    ClassLoader classLoader = theClass.getClassLoader();
+
+                    Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+                    if (clazz == null) {
+                        classLoader = Thread.currentThread().getContextClassLoader();
+                        clazz = loadClass(classLoader, fullQualifiedName);
+                    }
+                    return clazz;
+                }
+            });
+        } else {
+            ClassLoader classLoader = theClass.getClassLoader();
+
+            Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+            if (clazz == null) {
+                classLoader = Thread.currentThread().getContextClassLoader();
+                clazz = loadClass(classLoader, fullQualifiedName);
+            }
+            return clazz;
+        }
+    }
+
+    /**
+     * <p>
+     * Loads a class from the specified {@link ClassLoader} using the <code>fullQualifiedName</code> supplied.
+     * </p>
+     *
+     * @param classLoader
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final ClassLoader classLoader, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    try {
+                        return classLoader.loadClass(fullQualifiedName);
+                    } catch (ClassNotFoundException e) {
+                    }
+                    return null;
+                }
+            });
+        } else {
+            try {
+                return classLoader.loadClass(fullQualifiedName);
+            } catch (ClassNotFoundException e) {
+            }
+            return null;
+        }
+    }
+
+    /**
+     * <p>Returns a system property value using the specified <code>key</code>. If not found the
+     * <code>defaultValue</code> will be returned.</p>
+     *
+     * @param key
+     * @param defaultValue
+     *
+     * @return
+     */
+    static String getSystemProperty(final String key, final String defaultValue) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty(key, defaultValue);
+                }
+            });
+        } else {
+            return System.getProperty(key, defaultValue);
+        }
+    }
+
+    /**
+     * Load a resource based on the passed {@link Class} classloader. Failing which try with the Thread Context CL
+     *
+     * @param clazz
+     * @param resourceName
+     *
+     * @return
+     */
+    static URL loadResource(final Class<?> clazz, final String resourceName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<URL>() {
+                public URL run() {
+                    URL url = null;
+                    ClassLoader clazzLoader = clazz.getClassLoader();
+                    url = clazzLoader.getResource(resourceName);
+
+                    if (url == null) {
+                        clazzLoader = Thread.currentThread().getContextClassLoader();
+                        url = clazzLoader.getResource(resourceName);
+                    }
+
+                    return url;
+                }
+            });
+        } else {
+            URL url = null;
+            ClassLoader clazzLoader = clazz.getClassLoader();
+            url = clazzLoader.getResource(resourceName);
+
+            if (url == null) {
+                clazzLoader = Thread.currentThread().getContextClassLoader();
+                url = clazzLoader.getResource(resourceName);
+            }
+
+            return url;
+        }
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/response/SecurityActions.java b/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/response/SecurityActions.java
new file mode 100755
index 0000000..6cd7266
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/response/SecurityActions.java
@@ -0,0 +1,122 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.api.saml.v2.response;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ */
+class SecurityActions {
+
+    /**
+     * <p>
+     * Loads a {@link Class} using the <code>fullQualifiedName</code> supplied. This method tries first to load from
+     * the
+     * specified {@link Class}, if not found it will try to load from using TCL.
+     * </p>
+     *
+     * @param theClass
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final Class<?> theClass, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    ClassLoader classLoader = theClass.getClassLoader();
+
+                    Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+                    if (clazz == null) {
+                        classLoader = Thread.currentThread().getContextClassLoader();
+                        clazz = loadClass(classLoader, fullQualifiedName);
+                    }
+                    return clazz;
+                }
+            });
+        } else {
+            ClassLoader classLoader = theClass.getClassLoader();
+
+            Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+            if (clazz == null) {
+                classLoader = Thread.currentThread().getContextClassLoader();
+                clazz = loadClass(classLoader, fullQualifiedName);
+            }
+            return clazz;
+        }
+    }
+
+    /**
+     * <p>
+     * Loads a class from the specified {@link ClassLoader} using the <code>fullQualifiedName</code> supplied.
+     * </p>
+     *
+     * @param classLoader
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final ClassLoader classLoader, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    try {
+                        return classLoader.loadClass(fullQualifiedName);
+                    } catch (ClassNotFoundException e) {
+                    }
+                    return null;
+                }
+            });
+        } else {
+            try {
+                return classLoader.loadClass(fullQualifiedName);
+            } catch (ClassNotFoundException e) {
+            }
+            return null;
+        }
+    }
+
+    /**
+     * <p>Returns a system property value using the specified <code>key</code>. If not found the
+     * <code>defaultValue</code> will be returned.</p>
+     *
+     * @param key
+     * @param defaultValue
+     *
+     * @return
+     */
+    static String getSystemProperty(final String key, final String defaultValue) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty(key, defaultValue);
+                }
+            });
+        } else {
+            return System.getProperty(key, defaultValue);
+        }
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/sig/SAML2Signature.java b/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/sig/SAML2Signature.java
new file mode 100755
index 0000000..b4cf8a5
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/sig/SAML2Signature.java
@@ -0,0 +1,238 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.api.saml.v2.sig;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.processing.api.saml.v2.request.SAML2Request;
+import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
+import org.keycloak.saml.processing.core.util.SignatureUtilTransferObject;
+import org.keycloak.saml.processing.core.util.XMLSignatureUtil;
+import org.keycloak.dom.saml.v2.protocol.RequestAbstractType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.xpath.XPathException;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+
+/**
+ * Class that deals with SAML2 Signature
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @author alessio.soldano@jboss.com
+ * @since May 26, 2009
+ */
+public class SAML2Signature {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    private static final String ID_ATTRIBUTE_NAME = "ID";
+
+    private String signatureMethod = SignatureMethod.RSA_SHA1;
+
+    private String digestMethod = DigestMethod.SHA1;
+
+    private Node sibling;
+
+    /**
+     * Set the X509Certificate if X509Data is needed in signed info
+     */
+    private X509Certificate x509Certificate;
+
+    public String getSignatureMethod() {
+        return signatureMethod;
+    }
+
+    public void setSignatureMethod(String signatureMethod) {
+        this.signatureMethod = signatureMethod;
+    }
+
+    public String getDigestMethod() {
+        return digestMethod;
+    }
+
+    public void setDigestMethod(String digestMethod) {
+        this.digestMethod = digestMethod;
+    }
+
+    public void setNextSibling(Node sibling) {
+        this.sibling = sibling;
+    }
+
+    /**
+     * Set to false, if you do not want to include keyinfo in the signature
+     *
+     * @param val
+     *
+     * @since v2.0.1
+     */
+    public void setSignatureIncludeKeyInfo(boolean val) {
+        if (!val) {
+            XMLSignatureUtil.setIncludeKeyInfoInSignature(false);
+        }
+    }
+
+    /**
+     * Set the {@link X509Certificate} if you desire
+     * to have the SignedInfo have X509 Data
+     *
+     * This method needs to be called before any of the sign methods.
+     *
+     * @param x509Certificate
+     *
+     * @since v2.5.0
+     */
+    public void setX509Certificate(X509Certificate x509Certificate) {
+        this.x509Certificate = x509Certificate;
+    }
+
+    /**
+     * Sign an Document at the root
+     *
+     * @param keyPair Key Pair
+     *
+     * @return
+     *
+     * @throws ParserConfigurationException
+     * @throws XMLSignatureException
+     * @throws MarshalException
+     * @throws GeneralSecurityException
+     */
+    public Document sign(Document doc, String referenceID, KeyPair keyPair, String canonicalizationMethodType) throws ParserConfigurationException,
+            GeneralSecurityException, MarshalException, XMLSignatureException {
+        String referenceURI = "#" + referenceID;
+
+        configureIdAttribute(doc);
+
+        if (sibling != null) {
+            SignatureUtilTransferObject dto = new SignatureUtilTransferObject();
+            dto.setDocumentToBeSigned(doc);
+            dto.setKeyPair(keyPair);
+            dto.setDigestMethod(digestMethod);
+            dto.setSignatureMethod(signatureMethod);
+            dto.setReferenceURI(referenceURI);
+            dto.setNextSibling(sibling);
+
+            if (x509Certificate != null) {
+                dto.setX509Certificate(x509Certificate);
+            }
+
+            return XMLSignatureUtil.sign(dto, canonicalizationMethodType);
+        }
+        return XMLSignatureUtil.sign(doc, keyPair, digestMethod, signatureMethod, referenceURI, canonicalizationMethodType);
+    }
+
+    /**
+     * Sign a SAML Document
+     *
+     * @param samlDocument
+     * @param keypair
+     *
+     * @throws org.keycloak.saml.common.exceptions.ProcessingException
+     */
+    public void signSAMLDocument(Document samlDocument, KeyPair keypair, String canonicalizationMethodType) throws ProcessingException {
+        // Get the ID from the root
+        String id = samlDocument.getDocumentElement().getAttribute(ID_ATTRIBUTE_NAME);
+        try {
+            sign(samlDocument, id, keypair, canonicalizationMethodType);
+        } catch (Exception e) {
+            throw new ProcessingException(logger.signatureError(e));
+        }
+    }
+
+    /**
+     * Validate the SAML2 Document
+     *
+     * @param signedDocument
+     * @param publicKey
+     *
+     * @return
+     *
+     * @throws ProcessingException
+     */
+    public boolean validate(Document signedDocument, PublicKey publicKey) throws ProcessingException {
+        try {
+            configureIdAttribute(signedDocument);
+            return XMLSignatureUtil.validate(signedDocument, publicKey);
+        } catch (MarshalException me) {
+            throw new ProcessingException(logger.signatureError(me));
+        } catch (XMLSignatureException xse) {
+            throw new ProcessingException(logger.signatureError(xse));
+        }
+    }
+
+    /**
+     * Given a {@link Document}, find the {@link Node} which is the sibling of the Issuer element
+     *
+     * @param doc
+     *
+     * @return
+     */
+    public Node getNextSiblingOfIssuer(Document doc) {
+        // Find the sibling of Issuer
+        NodeList nl = doc.getElementsByTagNameNS(JBossSAMLURIConstants.ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get());
+        if (nl.getLength() > 0) {
+            Node issuer = nl.item(0);
+
+            return issuer.getNextSibling();
+        }
+        return null;
+    }
+
+    /**
+     * <p>
+     * Sets the IDness of the ID attribute. Santuario 1.5.1 does not assumes IDness based on attribute names anymore.
+     * This
+     * method should be called before signing/validating a saml document.
+     * </p>
+     *
+     * @param document SAML document to have its ID attribute configured.
+     */
+    private void configureIdAttribute(Document document) {
+        // Estabilish the IDness of the ID attribute.
+        document.getDocumentElement().setIdAttribute(ID_ATTRIBUTE_NAME, true);
+
+        NodeList nodes = document.getElementsByTagNameNS(JBossSAMLURIConstants.ASSERTION_NSURI.get(),
+                JBossSAMLConstants.ASSERTION.get());
+
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node n = nodes.item(i);
+            if (n instanceof Element) {
+                ((Element) n).setIdAttribute(ID_ATTRIBUTE_NAME, true);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/api/util/DeflateUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/api/util/DeflateUtil.java
new file mode 100755
index 0000000..eee41bb
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/api/util/DeflateUtil.java
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.api.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterInputStream;
+
+/**
+ * Encoder of saml messages based on DEFLATE compression
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 11, 2008
+ */
+public class DeflateUtil {
+
+    /**
+     * Apply DEFLATE encoding
+     *
+     * @param message
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public static byte[] encode(byte[] message) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Deflater deflater = new Deflater(Deflater.DEFLATED, true);
+        DeflaterOutputStream deflaterStream = new DeflaterOutputStream(baos, deflater);
+        deflaterStream.write(message);
+        deflaterStream.finish();
+
+        return baos.toByteArray();
+    }
+
+    /**
+     * Apply DEFLATE encoding
+     *
+     * @param message
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public static byte[] encode(String message) throws IOException {
+        return encode(message.getBytes());
+    }
+
+    /**
+     * DEFLATE decoding
+     *
+     * @param msgToDecode the message that needs decoding
+     *
+     * @return
+     */
+    public static InputStream decode(byte[] msgToDecode) {
+        ByteArrayInputStream bais = new ByteArrayInputStream(msgToDecode);
+        return new InflaterInputStream(bais, new Inflater(true));
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/constants/AttributeConstants.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/constants/AttributeConstants.java
new file mode 100755
index 0000000..97fe7c1
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/constants/AttributeConstants.java
@@ -0,0 +1,34 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.constants;
+
+/**
+ * Constants for attributes
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Aug 31, 2009
+ */
+public interface AttributeConstants {
+
+    String ROLES = "roles";
+
+    /**
+     * Default identifier in the saml2 attribute statements to indicate role *
+     */
+    String ROLE_IDENTIFIER_ASSERTION = "Role";
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/constants/PicketLinkFederationConstants.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/constants/PicketLinkFederationConstants.java
new file mode 100755
index 0000000..29d5058
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/constants/PicketLinkFederationConstants.java
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.constants;
+
+/**
+ * Constants useful to the JBoss Identity Federation project
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Feb 23, 2009
+ */
+public interface PicketLinkFederationConstants {
+
+    /**
+     * Flag to indicate whether JAXB Schema Validation is turned on
+     */
+    String JAXB_SCHEMA_VALIDATION = "org.picketlink.jaxb.schema.validation";
+
+    String SCHEMA_IDFED = "schema/config/picketlink-fed.xsd";
+    String SCHEMA_IDFED_HANDLER = "schema/config/picketlink-fed-handler.xsd";
+    String DSA_SIGNATURE_ALGORITHM = "SHA1withDSA";
+    String RSA_SIGNATURE_ALGORITHM = "SHA1withRSA";
+
+    // File Based Meta data Configuration Constants
+    String SERIALIZATION_EXTENSION = ".SER";
+    String FILE_STORE_DIRECTORY = "/picketlink-store";
+    String IDP_PROPERTIES = "/identityproviders.properties";
+    String SP_PROPERTIES = "/serviceproviders.properties";
+
+    String SALT = "salt";
+    String ITERATION_COUNT = "iterationCount";
+
+    String PBE_ALGORITHM = "PBEwithMD5andDES";
+    // Prefix to indicate a particular configuration property value is masked
+    String PASS_MASK_PREFIX = "MASK-";
+
+    RuntimePermission RUNTIME_PERMISSION_CORE = new RuntimePermission("org.picketlink.core");
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/AbstractDescriptorParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/AbstractDescriptorParser.java
new file mode 100755
index 0000000..bf1031c
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/AbstractDescriptorParser.java
@@ -0,0 +1,66 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml.metadata;
+
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.AbstractParser;
+
+import javax.xml.stream.EventFilter;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.XMLEvent;
+
+/**
+ * <p>Abstract entity descriptor parser, which provides common parser functionality</p>
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public abstract class AbstractDescriptorParser extends AbstractParser {
+
+    protected XMLEventReader filterWhiteSpaceCharacters(XMLEventReader xmlEventReader) throws ParsingException {
+
+        XMLInputFactory xmlInputFactory = getXMLInputFactory();
+
+        try {
+            xmlEventReader = xmlInputFactory.createFilteredReader(xmlEventReader, new EventFilter() {
+                public boolean accept(XMLEvent xmlEvent) {
+                    // We are going to disregard characters that are new line and whitespace
+                    if (xmlEvent.isCharacters()) {
+                        Characters chars = xmlEvent.asCharacters();
+                        String data = chars.getData();
+                        data = valid(data) ? data.trim() : null;
+                        return valid(data);
+                    } else {
+                        return xmlEvent.isStartElement() || xmlEvent.isEndElement();
+                    }
+                }
+
+                private boolean valid(String str) {
+                    return str != null && str.length() > 0;
+                }
+            });
+            return xmlEventReader;
+        } catch (XMLStreamException e) {
+            throw new ParsingException(e);
+        }
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/SAMLEntitiesDescriptorParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/SAMLEntitiesDescriptorParser.java
new file mode 100755
index 0000000..ad174b3
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/SAMLEntitiesDescriptorParser.java
@@ -0,0 +1,123 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml.metadata;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v2.metadata.EntitiesDescriptorType;
+import org.keycloak.dom.saml.v2.metadata.ExtensionsType;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+/**
+ * Parse the SAML Entities Descriptor
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jan 31, 2011
+ */
+public class SAMLEntitiesDescriptorParser extends AbstractDescriptorParser implements ParserNamespaceSupport {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    private final String EDT = JBossSAMLConstants.ENTITIES_DESCRIPTOR.get();
+
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+
+        xmlEventReader = filterWhiteSpaceCharacters(xmlEventReader);
+
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.validate(startElement, EDT);
+
+        EntitiesDescriptorType entitiesDescriptorType = new EntitiesDescriptorType();
+
+        // Parse the attributes
+        Attribute validUntil = startElement.getAttributeByName(new QName(JBossSAMLConstants.VALID_UNTIL.get()));
+        if (validUntil != null) {
+            String validUntilValue = StaxParserUtil.getAttributeValue(validUntil);
+            entitiesDescriptorType.setValidUntil(XMLTimeUtil.parse(validUntilValue));
+        }
+
+        Attribute id = startElement.getAttributeByName(new QName(JBossSAMLConstants.ID.get()));
+        if (id != null) {
+            entitiesDescriptorType.setID(StaxParserUtil.getAttributeValue(id));
+        }
+
+        Attribute name = startElement.getAttributeByName(new QName(JBossSAMLConstants.NAME.get()));
+        if (name != null) {
+            entitiesDescriptorType.setName(StaxParserUtil.getAttributeValue(name));
+        }
+
+        Attribute cacheDuration = startElement.getAttributeByName(new QName(JBossSAMLConstants.CACHE_DURATION.get()));
+        if (cacheDuration != null) {
+            entitiesDescriptorType
+                    .setCacheDuration(XMLTimeUtil.parseAsDuration(StaxParserUtil.getAttributeValue(cacheDuration)));
+        }
+
+        // Get the Child Elements
+        while (xmlEventReader.hasNext()) {
+            XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
+            if (xmlEvent instanceof EndElement) {
+                StaxParserUtil.validate((EndElement) xmlEvent, EDT);
+                StaxParserUtil.getNextEndElement(xmlEventReader);
+                break;
+            }
+            startElement = (StartElement) xmlEvent;
+            String localPart = startElement.getName().getLocalPart();
+
+            if (JBossSAMLConstants.ENTITY_DESCRIPTOR.get().equals(localPart)) {
+                SAMLEntityDescriptorParser entityParser = new SAMLEntityDescriptorParser();
+                entitiesDescriptorType.addEntityDescriptor(entityParser.parse(xmlEventReader));
+            } else if (JBossSAMLConstants.EXTENSIONS.get().equalsIgnoreCase(localPart)) {
+                entitiesDescriptorType.setExtensions(parseExtensions(xmlEventReader));
+            } else if (JBossSAMLConstants.ENTITIES_DESCRIPTOR.get().equalsIgnoreCase(localPart)) {
+                SAMLEntitiesDescriptorParser parser = new SAMLEntitiesDescriptorParser();
+                entitiesDescriptorType.addEntityDescriptor(parser.parse(xmlEventReader));
+            } else if (localPart.equals(JBossSAMLConstants.SIGNATURE.get())) {
+                entitiesDescriptorType.setSignature(StaxParserUtil.getDOMElement(xmlEventReader));
+            } else
+                throw logger.parserUnknownTag(localPart, startElement.getLocation());
+        }
+        return entitiesDescriptorType;
+    }
+
+    public boolean supports(QName qname) {
+        String nsURI = qname.getNamespaceURI();
+        String localPart = qname.getLocalPart();
+
+        return nsURI.equals(JBossSAMLURIConstants.ASSERTION_NSURI.get()) && localPart.equals(EDT);
+    }
+
+    private ExtensionsType parseExtensions(XMLEventReader xmlEventReader) throws ParsingException {
+        ExtensionsType extensions = new ExtensionsType();
+        Element extElement = StaxParserUtil.getDOMElement(xmlEventReader);
+        extensions.setElement(extElement);
+        return extensions;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11AssertionParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11AssertionParser.java
new file mode 100755
index 0000000..a16c511
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11AssertionParser.java
@@ -0,0 +1,178 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.DocumentUtil;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.common.util.StringUtil;
+import org.keycloak.saml.processing.core.parsers.util.SAML11ParserUtil;
+import org.keycloak.saml.processing.core.saml.v1.SAML11Constants;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v1.assertion.SAML11AssertionType;
+import org.keycloak.dom.saml.v1.assertion.SAML11AttributeStatementType;
+import org.keycloak.dom.saml.v1.assertion.SAML11AuthenticationStatementType;
+import org.keycloak.dom.saml.v1.assertion.SAML11AuthorizationDecisionStatementType;
+import org.keycloak.dom.saml.v1.assertion.SAML11ConditionsType;
+import org.keycloak.dom.saml.v1.assertion.SAML11SubjectStatementType;
+import org.keycloak.dom.saml.v1.assertion.SAML11SubjectType;
+import org.w3c.dom.Element;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+/**
+ * Parse the saml assertion
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Oct 12, 2010
+ */
+public class SAML11AssertionParser implements ParserNamespaceSupport {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    private final String ASSERTION = JBossSAMLConstants.ASSERTION.get();
+
+    public SAML11AssertionType fromElement(Element element) throws ConfigurationException, ProcessingException,
+            ParsingException {
+        XMLEventReader xmlEventReader = StaxParserUtil.getXMLEventReader(DocumentUtil.getNodeAsStream(element));
+        return (SAML11AssertionType) parse(xmlEventReader);
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#parse(XMLEventReader)}
+     */
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        StartElement startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+
+        startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+
+        // Special case: Encrypted Assertion
+        StaxParserUtil.validate(startElement, ASSERTION);
+        SAML11AssertionType assertion = parseBaseAttributes(startElement);
+
+        Attribute issuerAttribute = startElement.getAttributeByName(new QName(SAML11Constants.ISSUER));
+        String issuer = StaxParserUtil.getAttributeValue(issuerAttribute);
+        assertion.setIssuer(issuer);
+
+        // Peek at the next event
+        while (xmlEventReader.hasNext()) {
+            XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
+            if (xmlEvent == null)
+                break;
+
+            if (xmlEvent instanceof EndElement) {
+                xmlEvent = StaxParserUtil.getNextEvent(xmlEventReader);
+                EndElement endElement = (EndElement) xmlEvent;
+                String endElementTag = StaxParserUtil.getEndElementName(endElement);
+                if (endElementTag.equals(JBossSAMLConstants.ASSERTION.get()))
+                    break;
+                else
+                    throw logger.parserUnknownEndElement(endElementTag);
+            }
+
+            StartElement peekedElement = null;
+
+            if (xmlEvent instanceof StartElement) {
+                peekedElement = (StartElement) xmlEvent;
+            } else {
+                peekedElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            }
+            if (peekedElement == null)
+                break;
+
+            String tag = StaxParserUtil.getStartElementName(peekedElement);
+
+            if (tag.equals(JBossSAMLConstants.SIGNATURE.get())) {
+                assertion.setSignature(StaxParserUtil.getDOMElement(xmlEventReader));
+            } else if (JBossSAMLConstants.ISSUER.get().equalsIgnoreCase(tag)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                issuer = StaxParserUtil.getElementText(xmlEventReader);
+
+                assertion.setIssuer(issuer);
+            } else if (JBossSAMLConstants.SUBJECT.get().equalsIgnoreCase(tag)) {
+                SAML11SubjectParser subjectParser = new SAML11SubjectParser();
+                SAML11SubjectType subject = (SAML11SubjectType) subjectParser.parse(xmlEventReader);
+                SAML11SubjectStatementType subStat = new SAML11SubjectStatementType();
+                subStat.setSubject(subject);
+            } else if (JBossSAMLConstants.CONDITIONS.get().equalsIgnoreCase(tag)) {
+                startElement = (StartElement) xmlEvent;
+
+                SAML11ConditionsType conditions = SAML11ParserUtil.parseSAML11Conditions(xmlEventReader);
+                assertion.setConditions(conditions);
+            } else if (SAML11Constants.AUTHENTICATION_STATEMENT.equals(tag)) {
+                startElement = (StartElement) xmlEvent;
+                SAML11AuthenticationStatementType authStat = SAML11ParserUtil.parseAuthenticationStatement(xmlEventReader);
+                assertion.add(authStat);
+            } else if (SAML11Constants.ATTRIBUTE_STATEMENT.equalsIgnoreCase(tag)) {
+                SAML11AttributeStatementType attributeStatementType = SAML11ParserUtil
+                        .parseSAML11AttributeStatement(xmlEventReader);
+                assertion.add(attributeStatementType);
+            } else if (SAML11Constants.AUTHORIZATION_DECISION_STATEMENT.equalsIgnoreCase(tag)) {
+                SAML11AuthorizationDecisionStatementType authzStat = SAML11ParserUtil
+                        .parseSAML11AuthorizationDecisionStatement(xmlEventReader);
+                assertion.add(authzStat);
+            } else
+                throw logger.parserUnknownTag(tag, peekedElement.getLocation());
+        }
+        return assertion;
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#supports(QName)}
+     */
+    public boolean supports(QName qname) {
+        String nsURI = qname.getNamespaceURI();
+        String localPart = qname.getLocalPart();
+
+        return nsURI.equals(JBossSAMLURIConstants.ASSERTION_NSURI.get())
+                && localPart.equals(JBossSAMLConstants.ASSERTION.get());
+    }
+
+    private SAML11AssertionType parseBaseAttributes(StartElement nextElement) throws ParsingException {
+        Attribute idAttribute = nextElement.getAttributeByName(new QName(SAML11Constants.ASSERTIONID));
+        if (idAttribute == null)
+            throw logger.parserRequiredAttribute("AssertionID");
+        String id = StaxParserUtil.getAttributeValue(idAttribute);
+
+        Attribute majVersionAttribute = nextElement.getAttributeByName(new QName(SAML11Constants.MAJOR_VERSION));
+        String majVersion = StaxParserUtil.getAttributeValue(majVersionAttribute);
+        StringUtil.match("1", majVersion);
+
+        Attribute minVersionAttribute = nextElement.getAttributeByName(new QName(SAML11Constants.MINOR_VERSION));
+        String minVersion = StaxParserUtil.getAttributeValue(minVersionAttribute);
+        StringUtil.match("1", minVersion);
+
+        Attribute issueInstantAttribute = nextElement.getAttributeByName(new QName(JBossSAMLConstants.ISSUE_INSTANT.get()));
+        XMLGregorianCalendar issueInstant = XMLTimeUtil.parse(StaxParserUtil.getAttributeValue(issueInstantAttribute));
+
+        return new SAML11AssertionType(id, issueInstant);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11RequestParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11RequestParser.java
new file mode 100755
index 0000000..6abf6c6
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11RequestParser.java
@@ -0,0 +1,116 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.processing.core.parsers.util.SAML11ParserUtil;
+import org.keycloak.saml.processing.core.saml.v1.SAML11Constants;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v1.protocol.SAML11AttributeQueryType;
+import org.keycloak.dom.saml.v1.protocol.SAML11AuthenticationQueryType;
+import org.keycloak.dom.saml.v1.protocol.SAML11AuthorizationDecisionQueryType;
+import org.keycloak.dom.saml.v1.protocol.SAML11RequestType;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+
+/**
+ * Parse the SAML2 AuthnRequest
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since June 24, 2011
+ */
+public class SAML11RequestParser implements ParserNamespaceSupport {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    protected SAML11RequestType parseRequiredAttributes(StartElement startElement) throws ParsingException {
+        Attribute idAttr = startElement.getAttributeByName(new QName(SAML11Constants.REQUEST_ID));
+        if (idAttr == null)
+            throw logger.parserRequiredAttribute(SAML11Constants.REQUEST_ID);
+
+        String id = StaxParserUtil.getAttributeValue(idAttr);
+
+        Attribute issueInstantAttr = startElement.getAttributeByName(new QName(SAML11Constants.ISSUE_INSTANT));
+        if (issueInstantAttr == null)
+            throw logger.parserRequiredAttribute(SAML11Constants.ISSUE_INSTANT);
+        XMLGregorianCalendar issueInstant = XMLTimeUtil.parse(StaxParserUtil.getAttributeValue(issueInstantAttr));
+        return new SAML11RequestType(id, issueInstant);
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#parse(XMLEventReader)}
+     */
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        // Get the startelement
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.validate(startElement, SAML11Constants.REQUEST);
+
+        SAML11RequestType request = parseRequiredAttributes(startElement);
+
+        while (xmlEventReader.hasNext()) {
+            // Let us peek at the next start element
+            startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            if (startElement == null)
+                break;
+
+            String elementName = StaxParserUtil.getStartElementName(startElement);
+
+            if (SAML11Constants.ATTRIBUTE_QUERY.equals(elementName)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                SAML11AttributeQueryType query = SAML11ParserUtil.parseSAML11AttributeQuery(xmlEventReader);
+                request.setQuery(query);
+            } else if (SAML11Constants.AUTHENTICATION_QUERY.equals(elementName)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                SAML11AuthenticationQueryType query = SAML11ParserUtil.parseSAML11AuthenticationQuery(xmlEventReader);
+                request.setQuery(query);
+            } else if (SAML11Constants.ASSERTION_ARTIFACT.equals(elementName)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                request.addAssertionArtifact(StaxParserUtil.getElementText(xmlEventReader));
+            } else if (SAML11Constants.AUTHORIZATION_DECISION_QUERY.equals(elementName)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                SAML11AuthorizationDecisionQueryType query = SAML11ParserUtil
+                        .parseSAML11AuthorizationDecisionQueryType(xmlEventReader);
+                request.setQuery(query);
+            } else if (elementName.equals(JBossSAMLConstants.SIGNATURE.get())) {
+                request.setSignature(StaxParserUtil.getDOMElement(xmlEventReader));
+            } else if (SAML11Constants.ASSERTION_ID_REF.equals(elementName)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                request.addAssertionIDRef(StaxParserUtil.getElementText(xmlEventReader));
+            } else
+                throw logger.parserUnknownStartElement(elementName, startElement.getLocation());
+        }
+        return request;
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#supports(QName)}
+     */
+    public boolean supports(QName qname) {
+        return JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(qname.getNamespaceURI());
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11ResponseParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11ResponseParser.java
new file mode 100755
index 0000000..8807834
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11ResponseParser.java
@@ -0,0 +1,189 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.processing.core.saml.v1.SAML11Constants;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v1.assertion.SAML11AssertionType;
+import org.keycloak.dom.saml.v1.protocol.SAML11ResponseType;
+import org.keycloak.dom.saml.v1.protocol.SAML11StatusCodeType;
+import org.keycloak.dom.saml.v1.protocol.SAML11StatusType;
+import org.keycloak.dom.saml.v2.protocol.StatusDetailType;
+import org.w3c.dom.Element;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+/**
+ * Parse the SAML 11 Response
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since 23 June 2011
+ */
+public class SAML11ResponseParser implements ParserNamespaceSupport {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    private final String RESPONSE = JBossSAMLConstants.RESPONSE.get();
+
+    /**
+     * @see {@link ParserNamespaceSupport#parse(XMLEventReader)}
+     */
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        // Get the startelement
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.validate(startElement, RESPONSE);
+
+        Attribute idAttr = startElement.getAttributeByName(new QName(SAML11Constants.RESPONSE_ID));
+        if (idAttr == null)
+            throw logger.parserRequiredAttribute(SAML11Constants.RESPONSE_ID);
+        String id = StaxParserUtil.getAttributeValue(idAttr);
+
+        Attribute issueInstant = startElement.getAttributeByName(new QName(SAML11Constants.ISSUE_INSTANT));
+        if (issueInstant == null)
+            throw logger.parserRequiredAttribute(SAML11Constants.ISSUE_INSTANT);
+        XMLGregorianCalendar issueInstantVal = XMLTimeUtil.parse(StaxParserUtil.getAttributeValue(issueInstant));
+
+        SAML11ResponseType response = new SAML11ResponseType(id, issueInstantVal);
+
+        while (xmlEventReader.hasNext()) {
+            // Let us peek at the next start element
+            startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            if (startElement == null)
+                break;
+            String elementName = StaxParserUtil.getStartElementName(startElement);
+            if (JBossSAMLConstants.SIGNATURE.get().equals(elementName)) {
+                Element sig = StaxParserUtil.getDOMElement(xmlEventReader);
+                response.setSignature(sig);
+            } else if (JBossSAMLConstants.ASSERTION.get().equals(elementName)) {
+                SAML11AssertionParser assertionParser = new SAML11AssertionParser();
+                response.add((SAML11AssertionType) assertionParser.parse(xmlEventReader));
+            } else if (JBossSAMLConstants.STATUS.get().equals(elementName)) {
+                response.setStatus(parseStatus(xmlEventReader));
+            } else
+                throw logger.parserUnknownStartElement(elementName, startElement.getLocation());
+        }
+
+        return response;
+    }
+
+    /**
+     * Parse the status element
+     *
+     * @param xmlEventReader
+     *
+     * @return
+     *
+     * @throws ParsingException
+     */
+    protected SAML11StatusType parseStatus(XMLEventReader xmlEventReader) throws ParsingException {
+        // Get the Start Element
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        String STATUS = JBossSAMLConstants.STATUS.get();
+        StaxParserUtil.validate(startElement, STATUS);
+
+        SAML11StatusType status = new SAML11StatusType();
+
+        while (xmlEventReader.hasNext()) {
+            startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+
+            if (startElement == null)
+                break;
+
+            QName startElementName = startElement.getName();
+            String elementTag = startElementName.getLocalPart();
+
+            SAML11StatusCodeType statusCode = null;
+
+            if (JBossSAMLConstants.STATUS_CODE.get().equals(elementTag)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                if (startElement == null)
+                    break;
+                Attribute valueAttr = startElement.getAttributeByName(new QName("Value"));
+                if (valueAttr != null) {
+                    statusCode = new SAML11StatusCodeType(new QName(StaxParserUtil.getAttributeValue(valueAttr)));
+                }
+                status.setStatusCode(statusCode);
+
+                // Peek at the next start element to see if it is status code
+                startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+                elementTag = startElement.getName().getLocalPart();
+                if (JBossSAMLConstants.STATUS_CODE.get().equals(elementTag)) {
+                    SAML11StatusCodeType subStatusCodeType = null;
+                    startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                    Attribute subValueAttr = startElement.getAttributeByName(new QName("Value"));
+                    if (subValueAttr != null) {
+                        subStatusCodeType = new SAML11StatusCodeType(new QName(StaxParserUtil.getAttributeValue(subValueAttr)));
+                    }
+                    statusCode.setStatusCode(subStatusCodeType);
+
+                    // Go to Status code end element.
+                    EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
+                    StaxParserUtil.validate(endElement, JBossSAMLConstants.STATUS_CODE.get());
+                    continue;
+                }
+            }
+            if (JBossSAMLConstants.STATUS_MESSAGE.get().equals(elementTag)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                if (startElement == null)
+                    break;
+                status.setStatusMessage(StaxParserUtil.getElementText(xmlEventReader));
+            }
+
+            if (JBossSAMLConstants.STATUS_DETAIL.get().equals(elementTag)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                if (startElement == null)
+                    break;
+                Element domElement = StaxParserUtil.getDOMElement(xmlEventReader);
+                StatusDetailType statusDetailType = new StatusDetailType();
+                statusDetailType.addStatusDetail(domElement);
+                status.setStatusDetail(statusDetailType);
+            }
+
+            // Get the next end element
+            XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
+            if (xmlEvent instanceof EndElement) {
+                EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
+                if (StaxParserUtil.matches(endElement, STATUS))
+                    break;
+                else
+                    throw logger.parserUnknownEndElement(StaxParserUtil.getEndElementName(endElement));
+            } else
+                break;
+        }
+        return status;
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#supports(QName)}
+     */
+    public boolean supports(QName qname) {
+        return SAML11Constants.PROTOCOL_11_NSURI.equals(qname.getNamespaceURI()) && RESPONSE.equals(qname.getLocalPart());
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11SubjectParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11SubjectParser.java
new file mode 100755
index 0000000..be38ea8
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAML11SubjectParser.java
@@ -0,0 +1,114 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.processing.core.parsers.util.SAML11ParserUtil;
+import org.keycloak.saml.processing.core.saml.v1.SAML11Constants;
+import org.keycloak.dom.saml.v1.assertion.SAML11NameIdentifierType;
+import org.keycloak.dom.saml.v1.assertion.SAML11SubjectConfirmationType;
+import org.keycloak.dom.saml.v1.assertion.SAML11SubjectType;
+import org.keycloak.dom.saml.v1.assertion.SAML11SubjectType.SAML11SubjectTypeChoice;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import java.net.URI;
+
+/**
+ * Parse the saml subject
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Oct 12, 2010
+ */
+public class SAML11SubjectParser implements ParserNamespaceSupport {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * @see {@link ParserNamespaceSupport#parse(XMLEventReader)}
+     */
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        StaxParserUtil.getNextEvent(xmlEventReader);
+
+        SAML11SubjectType subject = new SAML11SubjectType();
+
+        // Peek at the next event
+        while (xmlEventReader.hasNext()) {
+            XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
+            if (xmlEvent instanceof EndElement) {
+                EndElement endElement = (EndElement) xmlEvent;
+                if (StaxParserUtil.matches(endElement, JBossSAMLConstants.SUBJECT.get())) {
+                    endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
+                    break;
+                } else
+                    throw logger.parserUnknownEndElement(StaxParserUtil.getEndElementName(endElement));
+            }
+
+            StartElement peekedElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            if (peekedElement == null)
+                break;
+
+            String tag = StaxParserUtil.getStartElementName(peekedElement);
+
+            if (SAML11Constants.NAME_IDENTIFIER.equalsIgnoreCase(tag)) {
+                peekedElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                String val = StaxParserUtil.getElementText(xmlEventReader);
+                SAML11NameIdentifierType nameID = new SAML11NameIdentifierType(val);
+                Attribute formatAtt = peekedElement.getAttributeByName(new QName(SAML11Constants.FORMAT));
+                if (formatAtt != null) {
+                    nameID.setFormat(URI.create(StaxParserUtil.getAttributeValue(formatAtt)));
+                }
+
+                Attribute nameQAtt = peekedElement.getAttributeByName(new QName(SAML11Constants.NAME_QUALIFIER));
+                if (nameQAtt != null) {
+                    nameID.setNameQualifier(StaxParserUtil.getAttributeValue(nameQAtt));
+                }
+
+                SAML11SubjectTypeChoice subChoice = new SAML11SubjectTypeChoice(nameID);
+                subject.setChoice(subChoice);
+            } else if (JBossSAMLConstants.SUBJECT_CONFIRMATION.get().equalsIgnoreCase(tag)) {
+                SAML11SubjectConfirmationType subjectConfirmationType = SAML11ParserUtil
+                        .parseSAML11SubjectConfirmation(xmlEventReader);
+                subject.setSubjectConfirmation(subjectConfirmationType);
+            } else
+                throw logger.parserUnknownTag(tag, peekedElement.getLocation());
+        }
+        return subject;
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#supports(QName)}
+     */
+    public boolean supports(QName qname) {
+        String nsURI = qname.getNamespaceURI();
+        String localPart = qname.getLocalPart();
+
+        return nsURI.equals(JBossSAMLURIConstants.ASSERTION_NSURI.get()) && localPart.equals(JBossSAMLConstants.SUBJECT.get());
+    }
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLArtifactResolveParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLArtifactResolveParser.java
new file mode 100755
index 0000000..47ed782
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLArtifactResolveParser.java
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.ErrorCodes;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.dom.saml.v2.protocol.ArtifactResolveType;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.StartElement;
+
+/**
+ * Parse the {@link ArtifactResolveType}
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jul 1, 2011
+ */
+public class SAMLArtifactResolveParser extends SAMLRequestAbstractParser implements ParserNamespaceSupport {
+
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        // Get the startelement
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.validate(startElement, JBossSAMLConstants.ARTIFACT_RESOLVE.get());
+
+        ArtifactResolveType artifactResolve = parseBaseAttributes(startElement);
+
+        while (xmlEventReader.hasNext()) {
+            // Let us peek at the next start element
+            startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            if (startElement == null)
+                break;
+            super.parseCommonElements(startElement, xmlEventReader, artifactResolve);
+            String elementName = StaxParserUtil.getStartElementName(startElement);
+
+            if (JBossSAMLConstants.ARTIFACT.get().equals(elementName)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                artifactResolve.setArtifact(StaxParserUtil.getElementText(xmlEventReader));
+            } else if (JBossSAMLConstants.ISSUER.get().equals(elementName)) {
+                continue;
+            } else if (JBossSAMLConstants.SIGNATURE.get().equals(elementName)) {
+                continue;
+            } else
+                throw new RuntimeException(ErrorCodes.UNKNOWN_START_ELEMENT + elementName + "::location="
+                        + startElement.getLocation());
+        }
+        return artifactResolve;
+    }
+
+    public boolean supports(QName qname) {
+        return JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(qname.getNamespaceURI());
+    }
+
+    /**
+     * Parse the attributes at the authnrequesttype element
+     *
+     * @param startElement
+     *
+     * @return
+     *
+     * @throws ParsingException
+     */
+    private ArtifactResolveType parseBaseAttributes(StartElement startElement) throws ParsingException {
+        super.parseRequiredAttributes(startElement);
+        ArtifactResolveType authnRequest = new ArtifactResolveType(id, issueInstant);
+        // Let us get the attributes
+        super.parseBaseAttributes(startElement, authnRequest);
+
+        return authnRequest;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLArtifactResponseParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLArtifactResponseParser.java
new file mode 100755
index 0000000..8c28b77
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLArtifactResponseParser.java
@@ -0,0 +1,111 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.ErrorCodes;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.protocol.ArtifactResponseType;
+import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.StartElement;
+
+/**
+ * Parse the SAML Response
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since July 1, 2011
+ */
+public class SAMLArtifactResponseParser extends SAMLStatusResponseTypeParser implements ParserNamespaceSupport {
+
+    private final String ARTIFACT_RESPONSE = JBossSAMLConstants.ARTIFACT_RESPONSE.get();
+
+    /**
+     * @see {@link ParserNamespaceSupport#parse(XMLEventReader)}
+     */
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        // Get the startelement
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.validate(startElement, ARTIFACT_RESPONSE);
+
+        ArtifactResponseType response = (ArtifactResponseType) parseBaseAttributes(startElement);
+
+        while (xmlEventReader.hasNext()) {
+            // Let us peek at the next start element
+            startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            if (startElement == null)
+                break;
+            String elementName = StaxParserUtil.getStartElementName(startElement);
+
+            if (JBossSAMLConstants.ISSUER.get().equals(elementName)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                NameIDType issuer = new NameIDType();
+                issuer.setValue(StaxParserUtil.getElementText(xmlEventReader));
+                response.setIssuer(issuer);
+            } else if (JBossSAMLConstants.SIGNATURE.get().equals(elementName)) {
+                Element sig = StaxParserUtil.getDOMElement(xmlEventReader);
+                response.setSignature(sig);
+            } else if (JBossSAMLConstants.AUTHN_REQUEST.get().equals(elementName)) {
+                SAMLAuthNRequestParser authnParser = new SAMLAuthNRequestParser();
+                AuthnRequestType authn = (AuthnRequestType) authnParser.parse(xmlEventReader);
+                response.setAny(authn);
+            } else if (JBossSAMLConstants.RESPONSE.get().equals(elementName)) {
+                SAMLResponseParser authnParser = new SAMLResponseParser();
+                ResponseType authn = (ResponseType) authnParser.parse(xmlEventReader);
+                response.setAny(authn);
+            } else if (JBossSAMLConstants.STATUS.get().equals(elementName)) {
+                response.setStatus(parseStatus(xmlEventReader));
+            } else
+                throw new RuntimeException(ErrorCodes.UNKNOWN_START_ELEMENT + elementName + "::location="
+                        + startElement.getLocation());
+        }
+
+        return response;
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#supports(QName)}
+     */
+    public boolean supports(QName qname) {
+        return JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(qname.getNamespaceURI())
+                && ARTIFACT_RESPONSE.equals(qname.getLocalPart());
+    }
+
+    /**
+     * Parse the attributes at the response element
+     *
+     * @param startElement
+     *
+     * @return
+     *
+     * @throws ParsingException
+     */
+    protected StatusResponseType parseBaseAttributes(StartElement startElement) throws ParsingException {
+        ArtifactResponseType response = new ArtifactResponseType(super.parseBaseAttributes(startElement));
+        return response;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAssertionParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAssertionParser.java
new file mode 100755
index 0000000..8825448
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAssertionParser.java
@@ -0,0 +1,174 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.ErrorCodes;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.DocumentUtil;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.common.util.StringUtil;
+import org.keycloak.saml.processing.core.parsers.util.SAMLParserUtil;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
+import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
+import org.keycloak.dom.saml.v2.assertion.AuthnStatementType;
+import org.keycloak.dom.saml.v2.assertion.ConditionsType;
+import org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.assertion.SubjectType;
+import org.w3c.dom.Element;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+/**
+ * Parse the saml assertion
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Oct 12, 2010
+ */
+public class SAMLAssertionParser implements ParserNamespaceSupport {
+
+    private final String ASSERTION = JBossSAMLConstants.ASSERTION.get();
+
+    public AssertionType fromElement(Element element) throws ConfigurationException, ProcessingException, ParsingException {
+        XMLEventReader xmlEventReader = StaxParserUtil.getXMLEventReader(DocumentUtil.getNodeAsStream(element));
+        return (AssertionType) parse(xmlEventReader);
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#parse(XMLEventReader)}
+     */
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        StartElement startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+        String startElementName = StaxParserUtil.getStartElementName(startElement);
+        if (startElementName.equals(JBossSAMLConstants.ENCRYPTED_ASSERTION.get())) {
+            Element domElement = StaxParserUtil.getDOMElement(xmlEventReader);
+
+            EncryptedAssertionType encryptedAssertion = new EncryptedAssertionType();
+            encryptedAssertion.setEncryptedElement(domElement);
+            return encryptedAssertion;
+        }
+
+        startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+
+        // Special case: Encrypted Assertion
+        StaxParserUtil.validate(startElement, ASSERTION);
+        AssertionType assertion = parseBaseAttributes(startElement);
+
+        // Peek at the next event
+        while (xmlEventReader.hasNext()) {
+            XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
+            if (xmlEvent == null)
+                break;
+
+            if (xmlEvent instanceof EndElement) {
+                xmlEvent = StaxParserUtil.getNextEvent(xmlEventReader);
+                EndElement endElement = (EndElement) xmlEvent;
+                String endElementTag = StaxParserUtil.getEndElementName(endElement);
+                if (endElementTag.equals(JBossSAMLConstants.ASSERTION.get()))
+                    break;
+                else
+                    throw new RuntimeException(ErrorCodes.UNKNOWN_END_ELEMENT + endElementTag);
+            }
+
+            StartElement peekedElement = null;
+
+            if (xmlEvent instanceof StartElement) {
+                peekedElement = (StartElement) xmlEvent;
+            } else {
+                peekedElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            }
+            if (peekedElement == null)
+                break;
+
+            String tag = StaxParserUtil.getStartElementName(peekedElement);
+
+            if (tag.equals(JBossSAMLConstants.SIGNATURE.get())) {
+                assertion.setSignature(StaxParserUtil.getDOMElement(xmlEventReader));
+                continue;
+            }
+
+            if (JBossSAMLConstants.ISSUER.get().equalsIgnoreCase(tag)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                String issuerValue = StaxParserUtil.getElementText(xmlEventReader);
+                NameIDType issuer = new NameIDType();
+                issuer.setValue(issuerValue);
+
+                assertion.setIssuer(issuer);
+            } else if (JBossSAMLConstants.SUBJECT.get().equalsIgnoreCase(tag)) {
+                SAMLSubjectParser subjectParser = new SAMLSubjectParser();
+                assertion.setSubject((SubjectType) subjectParser.parse(xmlEventReader));
+            } else if (JBossSAMLConstants.CONDITIONS.get().equalsIgnoreCase(tag)) {
+                SAMLConditionsParser conditionsParser = new SAMLConditionsParser();
+                ConditionsType conditions = (ConditionsType) conditionsParser.parse(xmlEventReader);
+
+                assertion.setConditions(conditions);
+            } else if (JBossSAMLConstants.AUTHN_STATEMENT.get().equalsIgnoreCase(tag)) {
+                AuthnStatementType authnStatementType = SAMLParserUtil.parseAuthnStatement(xmlEventReader);
+                assertion.addStatement(authnStatementType);
+            } else if (JBossSAMLConstants.ATTRIBUTE_STATEMENT.get().equalsIgnoreCase(tag)) {
+                AttributeStatementType attributeStatementType = SAMLParserUtil.parseAttributeStatement(xmlEventReader);
+                assertion.addStatement(attributeStatementType);
+            } else if (JBossSAMLConstants.STATEMENT.get().equalsIgnoreCase(tag)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+
+                String xsiTypeValue = StaxParserUtil.getXSITypeValue(startElement);
+                throw new RuntimeException(ErrorCodes.UNKNOWN_XSI + xsiTypeValue);
+            } else
+                throw new RuntimeException(ErrorCodes.UNKNOWN_TAG + tag + "::location=" + peekedElement.getLocation());
+        }
+        return assertion;
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#supports(QName)}
+     */
+    public boolean supports(QName qname) {
+        String nsURI = qname.getNamespaceURI();
+        String localPart = qname.getLocalPart();
+
+        return nsURI.equals(JBossSAMLURIConstants.ASSERTION_NSURI.get())
+                && localPart.equals(JBossSAMLConstants.ASSERTION.get());
+    }
+
+    private AssertionType parseBaseAttributes(StartElement nextElement) throws ParsingException {
+        Attribute idAttribute = nextElement.getAttributeByName(new QName(JBossSAMLConstants.ID.get()));
+        String id = StaxParserUtil.getAttributeValue(idAttribute);
+
+        Attribute versionAttribute = nextElement.getAttributeByName(new QName(JBossSAMLConstants.VERSION.get()));
+        String version = StaxParserUtil.getAttributeValue(versionAttribute);
+        StringUtil.match(JBossSAMLConstants.VERSION_2_0.get(), version);
+
+        Attribute issueInstantAttribute = nextElement.getAttributeByName(new QName(JBossSAMLConstants.ISSUE_INSTANT.get()));
+        XMLGregorianCalendar issueInstant = XMLTimeUtil.parse(StaxParserUtil.getAttributeValue(issueInstantAttribute));
+
+        return new AssertionType(id, issueInstant);
+    }
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAttributeQueryParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAttributeQueryParser.java
new file mode 100755
index 0000000..7c1d38c
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAttributeQueryParser.java
@@ -0,0 +1,92 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.ErrorCodes;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.processing.core.parsers.util.SAMLParserUtil;
+import org.keycloak.dom.saml.v2.protocol.AttributeQueryType;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.StartElement;
+
+/**
+ * Parse the {@link org.keycloak.dom.saml.v2.protocol.ArtifactResolveType}
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jul 1, 2011
+ */
+public class SAMLAttributeQueryParser extends SAMLRequestAbstractParser implements ParserNamespaceSupport {
+
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        // Get the startelement
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.validate(startElement, JBossSAMLConstants.ATTRIBUTE_QUERY.get());
+
+        AttributeQueryType attributeQuery = parseBaseAttributes(startElement);
+
+        while (xmlEventReader.hasNext()) {
+            // Let us peek at the next start element
+            startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            if (startElement == null)
+                break;
+            super.parseCommonElements(startElement, xmlEventReader, attributeQuery);
+            String elementName = StaxParserUtil.getStartElementName(startElement);
+
+            if (JBossSAMLConstants.SUBJECT.get().equals(elementName)) {
+                attributeQuery.setSubject(getSubject(xmlEventReader));
+            } else if (JBossSAMLConstants.ATTRIBUTE.get().equals(elementName)) {
+                attributeQuery.add(SAMLParserUtil.parseAttribute(xmlEventReader));
+            } else if (JBossSAMLConstants.ISSUER.get().equals(elementName)) {
+                continue;
+            } else if (JBossSAMLConstants.SIGNATURE.get().equals(elementName)) {
+                continue;
+            } else
+                throw new RuntimeException(ErrorCodes.UNKNOWN_START_ELEMENT + elementName + "::location="
+                        + startElement.getLocation());
+        }
+        return attributeQuery;
+    }
+
+    public boolean supports(QName qname) {
+        return JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(qname.getNamespaceURI());
+    }
+
+    /**
+     * Parse the attributes at the authnrequesttype element
+     *
+     * @param startElement
+     *
+     * @return
+     *
+     * @throws ParsingException
+     */
+    private AttributeQueryType parseBaseAttributes(StartElement startElement) throws ParsingException {
+        super.parseRequiredAttributes(startElement);
+        AttributeQueryType authnRequest = new AttributeQueryType(id, issueInstant);
+        // Let us get the attributes
+        super.parseBaseAttributes(startElement, authnRequest);
+
+        return authnRequest;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAuthNRequestParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAuthNRequestParser.java
new file mode 100755
index 0000000..55a5cfd
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAuthNRequestParser.java
@@ -0,0 +1,212 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.ErrorCodes;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.dom.saml.v2.assertion.ConditionsType;
+import org.keycloak.dom.saml.v2.protocol.AuthnContextComparisonType;
+import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
+import org.keycloak.dom.saml.v2.protocol.NameIDPolicyType;
+import org.keycloak.dom.saml.v2.protocol.RequestedAuthnContextType;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import java.net.URI;
+
+/**
+ * Parse the SAML2 AuthnRequest
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Nov 2, 2010
+ */
+public class SAMLAuthNRequestParser extends SAMLRequestAbstractParser implements ParserNamespaceSupport {
+
+    /**
+     * @see {@link ParserNamespaceSupport#parse(XMLEventReader)}
+     */
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        // Get the startelement
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.validate(startElement, JBossSAMLConstants.AUTHN_REQUEST.get());
+
+        AuthnRequestType authnRequest = parseBaseAttributes(startElement);
+
+        while (xmlEventReader.hasNext()) {
+            // Let us peek at the next start element
+            startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            if (startElement == null)
+                break;
+            super.parseCommonElements(startElement, xmlEventReader, authnRequest);
+
+            String elementName = StaxParserUtil.getStartElementName(startElement);
+
+            if (JBossSAMLConstants.NAMEID_POLICY.get().equals(elementName)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                authnRequest.setNameIDPolicy(getNameIDPolicy(startElement));
+            } else if (JBossSAMLConstants.SUBJECT.get().equals(elementName)) {
+                authnRequest.setSubject(getSubject(xmlEventReader));
+            } else if (JBossSAMLConstants.CONDITIONS.get().equals(elementName)) {
+                authnRequest.setConditions((ConditionsType) (new SAMLConditionsParser()).parse(xmlEventReader));
+            } else if (JBossSAMLConstants.REQUESTED_AUTHN_CONTEXT.get().equals(elementName)) {
+                authnRequest.setRequestedAuthnContext(getRequestedAuthnContextType(xmlEventReader));
+            } else if (JBossSAMLConstants.ISSUER.get().equals(elementName)) {
+                continue;
+            } else if (JBossSAMLConstants.SIGNATURE.get().equals(elementName)) {
+                continue;
+            } else
+                throw new RuntimeException(ErrorCodes.UNKNOWN_START_ELEMENT + elementName + "::location="
+                        + startElement.getLocation());
+        }
+        return authnRequest;
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#supports(QName)}
+     */
+    public boolean supports(QName qname) {
+        return JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(qname.getNamespaceURI());
+    }
+
+    /**
+     * Parse the attributes at the authnrequesttype element
+     *
+     * @param startElement
+     *
+     * @return
+     *
+     * @throws ParsingException
+     */
+    private AuthnRequestType parseBaseAttributes(StartElement startElement) throws ParsingException {
+        super.parseRequiredAttributes(startElement);
+        AuthnRequestType authnRequest = new AuthnRequestType(id, issueInstant);
+        // Let us get the attributes
+        super.parseBaseAttributes(startElement, authnRequest);
+
+        Attribute assertionConsumerServiceURL = startElement.getAttributeByName(new QName(
+                JBossSAMLConstants.ASSERTION_CONSUMER_SERVICE_URL.get()));
+        if (assertionConsumerServiceURL != null) {
+            String uri = StaxParserUtil.getAttributeValue(assertionConsumerServiceURL);
+            authnRequest.setAssertionConsumerServiceURL(URI.create(uri));
+        }
+
+        Attribute assertionConsumerServiceIndex = startElement.getAttributeByName(new QName(
+                JBossSAMLConstants.ASSERTION_CONSUMER_SERVICE_INDEX.get()));
+        if (assertionConsumerServiceIndex != null)
+            authnRequest.setAssertionConsumerServiceIndex(Integer.parseInt(StaxParserUtil
+                    .getAttributeValue(assertionConsumerServiceIndex)));
+
+        Attribute protocolBinding = startElement.getAttributeByName(new QName(JBossSAMLConstants.PROTOCOL_BINDING.get()));
+        if (protocolBinding != null)
+            authnRequest.setProtocolBinding(URI.create(StaxParserUtil.getAttributeValue(protocolBinding)));
+
+        Attribute providerName = startElement.getAttributeByName(new QName(JBossSAMLConstants.PROVIDER_NAME.get()));
+        if (providerName != null)
+            authnRequest.setProviderName(StaxParserUtil.getAttributeValue(providerName));
+
+        Attribute forceAuthn = startElement.getAttributeByName(new QName(JBossSAMLConstants.FORCE_AUTHN.get()));
+        if (forceAuthn != null) {
+            authnRequest.setForceAuthn(Boolean.parseBoolean(StaxParserUtil.getAttributeValue(forceAuthn)));
+        }
+
+        Attribute isPassive = startElement.getAttributeByName(new QName(JBossSAMLConstants.IS_PASSIVE.get()));
+        if (isPassive != null) {
+            authnRequest.setIsPassive(Boolean.parseBoolean(StaxParserUtil.getAttributeValue(isPassive)));
+        }
+
+        Attribute attributeConsumingServiceIndex = startElement.getAttributeByName(new QName(
+                JBossSAMLConstants.ATTRIBUTE_CONSUMING_SERVICE_INDEX.get()));
+        if (attributeConsumingServiceIndex != null)
+            authnRequest.setAttributeConsumingServiceIndex(Integer.parseInt(StaxParserUtil
+                    .getAttributeValue(attributeConsumingServiceIndex)));
+
+        return authnRequest;
+    }
+
+    /**
+     * Get the NameIDPolicy
+     *
+     * @param startElement
+     *
+     * @return
+     */
+    private NameIDPolicyType getNameIDPolicy(StartElement startElement) {
+        NameIDPolicyType nameIDPolicy = new NameIDPolicyType();
+        Attribute format = startElement.getAttributeByName(new QName(JBossSAMLConstants.FORMAT.get()));
+        if (format != null)
+            nameIDPolicy.setFormat(URI.create(StaxParserUtil.getAttributeValue(format)));
+
+        Attribute allowCreate = startElement.getAttributeByName(new QName(JBossSAMLConstants.ALLOW_CREATE.get()));
+        if (allowCreate != null)
+            nameIDPolicy.setAllowCreate(Boolean.parseBoolean(StaxParserUtil.getAttributeValue(allowCreate)));
+
+        return nameIDPolicy;
+    }
+
+    private RequestedAuthnContextType getRequestedAuthnContextType(XMLEventReader xmlEventReader) throws ParsingException {
+        RequestedAuthnContextType ract = new RequestedAuthnContextType();
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.validate(startElement, JBossSAMLConstants.REQUESTED_AUTHN_CONTEXT.get());
+
+        Attribute comparison = startElement.getAttributeByName(new QName(JBossSAMLConstants.COMPARISON.get()));
+
+        if (comparison != null) {
+            ract.setComparison(AuthnContextComparisonType.fromValue(comparison.getValue()));
+        }
+
+        while (xmlEventReader.hasNext()) {
+            XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
+
+            if (xmlEvent instanceof EndElement) {
+                EndElement nextEndElement = (EndElement) xmlEvent;
+                if (StaxParserUtil.matches(nextEndElement, JBossSAMLConstants.REQUESTED_AUTHN_CONTEXT.get())) {
+                    nextEndElement = StaxParserUtil.getNextEndElement(xmlEventReader);
+                    break;
+                } else
+                    throw new RuntimeException(ErrorCodes.UNKNOWN_END_ELEMENT
+                            + StaxParserUtil.getEndElementName(nextEndElement));
+            }
+
+            String tag = null;
+
+            if (xmlEvent instanceof StartElement) {
+                StartElement peekedElement = (StartElement) xmlEvent;
+                tag = StaxParserUtil.getStartElementName(peekedElement);
+            }
+
+            startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+            String elName = StaxParserUtil.getStartElementName(startElement);
+
+            if (elName.equals(JBossSAMLConstants.AUTHN_CONTEXT_CLASS_REF.get())) {
+                String value = StaxParserUtil.getElementText(xmlEventReader);
+                ract.addAuthnContextClassRef(value);
+            } else
+                throw new RuntimeException(ErrorCodes.UNKNOWN_TAG + elName);
+        }
+
+        return ract;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLConditionsParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLConditionsParser.java
new file mode 100755
index 0000000..c9d44e4
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLConditionsParser.java
@@ -0,0 +1,174 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.ErrorCodes;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v2.assertion.AudienceRestrictionType;
+import org.keycloak.dom.saml.v2.assertion.ConditionsType;
+import org.keycloak.dom.saml.v2.assertion.OneTimeUseType;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import java.net.URI;
+
+/**
+ * Parse the <conditions> in the saml assertion
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Oct 14, 2010
+ */
+public class SAMLConditionsParser implements ParserNamespaceSupport {
+
+    /**
+     * @see {@link ParserNamespaceSupport#parse(XMLEventReader)}
+     */
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        // We are entering this method with <conditions> as the next start element
+        // and we have to exit after seeing the </conditions> end tag
+
+        StartElement conditionsElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.validate(conditionsElement, JBossSAMLConstants.CONDITIONS.get());
+
+        ConditionsType conditions = new ConditionsType();
+
+        String assertionNS = JBossSAMLURIConstants.ASSERTION_NSURI.get();
+
+        QName notBeforeQName = new QName("", JBossSAMLConstants.NOT_BEFORE.get());
+        QName notBeforeQNameWithNS = new QName(assertionNS, JBossSAMLConstants.NOT_BEFORE.get());
+
+        QName notAfterQName = new QName("", JBossSAMLConstants.NOT_ON_OR_AFTER.get());
+        QName notAfterQNameWithNS = new QName(assertionNS, JBossSAMLConstants.NOT_ON_OR_AFTER.get());
+
+        Attribute notBeforeAttribute = conditionsElement.getAttributeByName(notBeforeQName);
+        if (notBeforeAttribute == null)
+            notBeforeAttribute = conditionsElement.getAttributeByName(notBeforeQNameWithNS);
+
+        Attribute notAfterAttribute = conditionsElement.getAttributeByName(notAfterQName);
+        if (notAfterAttribute == null)
+            notAfterAttribute = conditionsElement.getAttributeByName(notAfterQNameWithNS);
+
+        if (notBeforeAttribute != null) {
+            String notBeforeValue = StaxParserUtil.getAttributeValue(notBeforeAttribute);
+            conditions.setNotBefore(XMLTimeUtil.parse(notBeforeValue));
+        }
+
+        if (notAfterAttribute != null) {
+            String notAfterValue = StaxParserUtil.getAttributeValue(notAfterAttribute);
+            conditions.setNotOnOrAfter(XMLTimeUtil.parse(notAfterValue));
+        }
+
+        // Let us find additional elements
+
+        while (xmlEventReader.hasNext()) {
+            XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
+
+            if (xmlEvent instanceof EndElement) {
+                EndElement nextEndElement = (EndElement) xmlEvent;
+                if (StaxParserUtil.matches(nextEndElement, JBossSAMLConstants.CONDITIONS.get())) {
+                    nextEndElement = StaxParserUtil.getNextEndElement(xmlEventReader);
+                    break;
+                } else
+                    throw new RuntimeException(ErrorCodes.UNKNOWN_END_ELEMENT
+                            + StaxParserUtil.getEndElementName(nextEndElement));
+            }
+
+            String tag = null;
+
+            if (xmlEvent instanceof StartElement) {
+                StartElement peekedElement = (StartElement) xmlEvent;
+                tag = StaxParserUtil.getStartElementName(peekedElement);
+            }
+
+            if (JBossSAMLConstants.AUDIENCE_RESTRICTION.get().equals(tag)) {
+                AudienceRestrictionType audienceRestriction = getAudienceRestriction(xmlEventReader);
+                conditions.addCondition(audienceRestriction);
+            } else if (JBossSAMLConstants.ONE_TIME_USE.get().equals(tag)) {
+                // just parses the onetimeuse tag. until now PL has no support for onetimeuse conditions.
+                StaxParserUtil.getNextStartElement(xmlEventReader);
+                OneTimeUseType oneTimeUseCondition = new OneTimeUseType();
+                conditions.addCondition(oneTimeUseCondition);
+
+                // Get the end tag
+                EndElement endElement = (EndElement) StaxParserUtil.getNextEvent(xmlEventReader);
+                StaxParserUtil.matches(endElement, JBossSAMLConstants.ONE_TIME_USE.get());
+            } else
+                throw new RuntimeException(ErrorCodes.UNKNOWN_TAG + tag + "::location=" + xmlEvent.getLocation());
+        }
+        return conditions;
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#supports(QName)}
+     */
+    public boolean supports(QName qname) {
+        String nsURI = qname.getNamespaceURI();
+        String localPart = qname.getLocalPart();
+
+        return nsURI.equals(JBossSAMLURIConstants.ASSERTION_NSURI.get())
+                && localPart.equals(JBossSAMLConstants.CONDITIONS.get());
+    }
+
+    /**
+     * Parse the <audiencerestriction/> element
+     *
+     * @param xmlEventReader
+     *
+     * @return
+     *
+     * @throws ParsingException
+     */
+    private AudienceRestrictionType getAudienceRestriction(XMLEventReader xmlEventReader) throws ParsingException {
+        StartElement audienceRestElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.matches(audienceRestElement, JBossSAMLConstants.AUDIENCE_RESTRICTION.get());
+
+        AudienceRestrictionType audience = new AudienceRestrictionType();
+
+        while (xmlEventReader.hasNext()) {
+            StartElement audienceElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+            if (!StaxParserUtil.matches(audienceElement, JBossSAMLConstants.AUDIENCE.get()))
+                break;
+
+            if (!StaxParserUtil.hasTextAhead(xmlEventReader))
+                throw new ParsingException(ErrorCodes.EXPECTED_TAG + "audienceValue");
+
+            String audienceValue = StaxParserUtil.getElementText(xmlEventReader);
+            audience.addAudience(URI.create(audienceValue));
+
+            XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
+            if (xmlEvent instanceof EndElement) {
+                EndElement endElement = (EndElement) xmlEvent;
+                if (StaxParserUtil.matches(endElement, JBossSAMLConstants.AUDIENCE_RESTRICTION.get())) {
+                    StaxParserUtil.getNextEvent(xmlEventReader); // Just get the end element
+                    break;
+                } else
+                    throw new RuntimeException(ErrorCodes.UNKNOWN_END_ELEMENT + StaxParserUtil.getEndElementName(endElement));
+            }
+        }
+        return audience;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParser.java
new file mode 100755
index 0000000..24c80f7
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParser.java
@@ -0,0 +1,129 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.ErrorCodes;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.AbstractParser;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.processing.core.parsers.saml.metadata.SAMLEntitiesDescriptorParser;
+import org.keycloak.saml.processing.core.parsers.saml.metadata.SAMLEntityDescriptorParser;
+import org.keycloak.saml.processing.core.saml.v1.SAML11Constants;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+/**
+ * Parse SAML payload
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Oct 12, 2010
+ */
+public class SAMLParser extends AbstractParser {
+
+    /**
+     * @see {@link org.keycloak.saml.common.parsers.ParserNamespaceSupport#parse(XMLEventReader)}
+     */
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        while (xmlEventReader.hasNext()) {
+            XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
+
+            if (xmlEvent instanceof StartElement) {
+                StartElement startElement = (StartElement) xmlEvent;
+                QName startElementName = startElement.getName();
+                String nsURI = startElementName.getNamespaceURI();
+
+                String localPart = startElementName.getLocalPart();
+
+                String elementName = StaxParserUtil.getStartElementName(startElement);
+
+                if (elementName.equalsIgnoreCase(JBossSAMLConstants.ASSERTION.get())
+                        || elementName.equals(JBossSAMLConstants.ENCRYPTED_ASSERTION.get())) {
+                    if (nsURI.equals(SAML11Constants.ASSERTION_11_NSURI)) {
+                        SAML11AssertionParser saml11AssertionParser = new SAML11AssertionParser();
+                        return saml11AssertionParser.parse(xmlEventReader);
+                    }
+                    SAMLAssertionParser assertionParser = new SAMLAssertionParser();
+                    return assertionParser.parse(xmlEventReader);
+                } else if (JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(nsURI)
+                        && JBossSAMLConstants.AUTHN_REQUEST.get().equals(startElementName.getLocalPart())) {
+                    SAMLAuthNRequestParser authNRequestParser = new SAMLAuthNRequestParser();
+                    return authNRequestParser.parse(xmlEventReader);
+                } else if (JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(nsURI)
+                        && JBossSAMLConstants.LOGOUT_REQUEST.get().equals(startElementName.getLocalPart())) {
+                    SAMLSloRequestParser sloParser = new SAMLSloRequestParser();
+                    return sloParser.parse(xmlEventReader);
+                } else if (JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(nsURI)
+                        && JBossSAMLConstants.LOGOUT_RESPONSE.get().equals(startElementName.getLocalPart())) {
+                    SAMLSloResponseParser sloParser = new SAMLSloResponseParser();
+                    return sloParser.parse(xmlEventReader);
+                } else if (JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(nsURI)
+                        && JBossSAMLConstants.RESPONSE.get().equals(startElementName.getLocalPart())) {
+                    SAMLResponseParser responseParser = new SAMLResponseParser();
+                    return responseParser.parse(xmlEventReader);
+                } else if (JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(nsURI)
+                        && JBossSAMLConstants.REQUEST_ABSTRACT.get().equals(startElementName.getLocalPart())) {
+                    String xsiTypeValue = StaxParserUtil.getXSITypeValue(startElement);
+                    throw new RuntimeException(ErrorCodes.UNKNOWN_XSI + xsiTypeValue);
+                } else if (JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(nsURI)
+                        && JBossSAMLConstants.ARTIFACT_RESOLVE.get().equals(startElementName.getLocalPart())) {
+                    SAMLArtifactResolveParser artifactResolverParser = new SAMLArtifactResolveParser();
+                    return artifactResolverParser.parse(xmlEventReader);
+                } else if (JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(nsURI)
+                        && JBossSAMLConstants.ARTIFACT_RESPONSE.get().equals(startElementName.getLocalPart())) {
+                    SAMLArtifactResponseParser responseParser = new SAMLArtifactResponseParser();
+                    return responseParser.parse(xmlEventReader);
+                } else if (JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(nsURI)
+                        && JBossSAMLConstants.ATTRIBUTE_QUERY.get().equals(startElementName.getLocalPart())) {
+                    SAMLAttributeQueryParser responseParser = new SAMLAttributeQueryParser();
+                    return responseParser.parse(xmlEventReader);
+                } else if (JBossSAMLConstants.ENTITY_DESCRIPTOR.get().equals(localPart)) {
+                    SAMLEntityDescriptorParser entityDescriptorParser = new SAMLEntityDescriptorParser();
+                    return entityDescriptorParser.parse(xmlEventReader);
+                } else if (JBossSAMLConstants.ENTITIES_DESCRIPTOR.get().equals(localPart)) {
+                    SAMLEntitiesDescriptorParser entityDescriptorParser = new SAMLEntitiesDescriptorParser();
+                    return entityDescriptorParser.parse(xmlEventReader);
+                } else if (SAML11Constants.PROTOCOL_11_NSURI.equals(nsURI)
+                        && JBossSAMLConstants.RESPONSE.get().equals(startElementName.getLocalPart())) {
+                    SAML11ResponseParser responseParser = new SAML11ResponseParser();
+                    return responseParser.parse(xmlEventReader);
+                } else if (SAML11Constants.PROTOCOL_11_NSURI.equals(nsURI)
+                        && SAML11Constants.REQUEST.equals(startElementName.getLocalPart())) {
+                    SAML11RequestParser reqParser = new SAML11RequestParser();
+                    return reqParser.parse(xmlEventReader);
+                } else
+                    throw new RuntimeException(ErrorCodes.UNKNOWN_START_ELEMENT + elementName + "::location="
+                            + startElement.getLocation());
+            } else {
+                StaxParserUtil.getNextEvent(xmlEventReader);
+            }
+        }
+        throw new RuntimeException(ErrorCodes.FAILED_PARSING + "SAML Parsing has failed");
+    }
+
+    /**
+     * @see {@link org.keycloak.saml.common.parsers.ParserNamespaceSupport#supports(QName)}
+     */
+    public boolean supports(QName qname) {
+        return JBossSAMLURIConstants.ASSERTION_NSURI.get().equals(qname.getNamespaceURI());
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLRequestAbstractParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLRequestAbstractParser.java
new file mode 100755
index 0000000..2c39451
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLRequestAbstractParser.java
@@ -0,0 +1,109 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.assertion.SubjectType;
+import org.keycloak.dom.saml.v2.protocol.RequestAbstractType;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+import java.net.URI;
+
+/**
+ * Base Class for SAML Request Parsing
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Nov 2, 2010
+ */
+public abstract class SAMLRequestAbstractParser {
+
+    protected static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    protected String id;
+
+    protected String version;
+
+    protected XMLGregorianCalendar issueInstant;
+
+    protected void parseRequiredAttributes(StartElement startElement) throws ParsingException {
+        Attribute idAttr = startElement.getAttributeByName(new QName(JBossSAMLConstants.ID.get()));
+        if (idAttr == null)
+            throw logger.parserRequiredAttribute("ID");
+
+        id = StaxParserUtil.getAttributeValue(idAttr);
+
+        Attribute versionAttr = startElement.getAttributeByName(new QName(JBossSAMLConstants.VERSION.get()));
+        if (versionAttr == null)
+            throw logger.parserRequiredAttribute("Version");
+        version = StaxParserUtil.getAttributeValue(versionAttr);
+
+        Attribute issueInstantAttr = startElement.getAttributeByName(new QName(JBossSAMLConstants.ISSUE_INSTANT.get()));
+        if (issueInstantAttr == null)
+            throw logger.parserRequiredAttribute("IssueInstant");
+        issueInstant = XMLTimeUtil.parse(StaxParserUtil.getAttributeValue(issueInstantAttr));
+    }
+
+    /**
+     * Parse the attributes that are common to all SAML Request Types
+     *
+     * @param startElement
+     * @param request
+     *
+     * @throws ParsingException
+     */
+    protected void parseBaseAttributes(StartElement startElement, RequestAbstractType request) throws ParsingException {
+        Attribute destinationAttr = startElement.getAttributeByName(new QName(JBossSAMLConstants.DESTINATION.get()));
+        if (destinationAttr != null)
+            request.setDestination(URI.create(StaxParserUtil.getAttributeValue(destinationAttr)));
+
+        Attribute consent = startElement.getAttributeByName(new QName(JBossSAMLConstants.CONSENT.get()));
+        if (consent != null)
+            request.setConsent(StaxParserUtil.getAttributeValue(consent));
+    }
+
+    protected void parseCommonElements(StartElement startElement, XMLEventReader xmlEventReader, RequestAbstractType request)
+            throws ParsingException {
+        if (startElement == null)
+            throw logger.parserNullStartElement();
+        String elementName = StaxParserUtil.getStartElementName(startElement);
+
+        if (JBossSAMLConstants.ISSUER.get().equals(elementName)) {
+            startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+            NameIDType issuer = new NameIDType();
+            issuer.setValue(StaxParserUtil.getElementText(xmlEventReader));
+            request.setIssuer(issuer);
+        } else if (JBossSAMLConstants.SIGNATURE.get().equals(elementName)) {
+            request.setSignature(StaxParserUtil.getDOMElement(xmlEventReader));
+        }
+    }
+
+    protected SubjectType getSubject(XMLEventReader xmlEventReader) throws ParsingException {
+        SAMLSubjectParser subjectParser = new SAMLSubjectParser();
+        return (SubjectType) subjectParser.parse(xmlEventReader);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLResponseParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLResponseParser.java
new file mode 100755
index 0000000..7d3c474
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLResponseParser.java
@@ -0,0 +1,108 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
+import org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType.RTChoiceType;
+import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.StartElement;
+
+/**
+ * Parse the SAML Response
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Nov 2, 2010
+ */
+public class SAMLResponseParser extends SAMLStatusResponseTypeParser implements ParserNamespaceSupport {
+
+    private final String RESPONSE = JBossSAMLConstants.RESPONSE.get();
+
+    /**
+     * @see {@link ParserNamespaceSupport#parse(XMLEventReader)}
+     */
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        // Get the startelement
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.validate(startElement, RESPONSE);
+
+        ResponseType response = (ResponseType) parseBaseAttributes(startElement);
+
+        while (xmlEventReader.hasNext()) {
+            // Let us peek at the next start element
+            startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            if (startElement == null)
+                break;
+            String elementName = StaxParserUtil.getStartElementName(startElement);
+
+            if (JBossSAMLConstants.ISSUER.get().equals(elementName)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                NameIDType issuer = new NameIDType();
+                issuer.setValue(StaxParserUtil.getElementText(xmlEventReader));
+                response.setIssuer(issuer);
+            } else if (JBossSAMLConstants.SIGNATURE.get().equals(elementName)) {
+                Element sig = StaxParserUtil.getDOMElement(xmlEventReader);
+                response.setSignature(sig);
+            } else if (JBossSAMLConstants.ASSERTION.get().equals(elementName)) {
+                SAMLAssertionParser assertionParser = new SAMLAssertionParser();
+                response.addAssertion(new RTChoiceType((AssertionType) assertionParser.parse(xmlEventReader)));
+            } else if (JBossSAMLConstants.STATUS.get().equals(elementName)) {
+                response.setStatus(parseStatus(xmlEventReader));
+            } else if (JBossSAMLConstants.ENCRYPTED_ASSERTION.get().equals(elementName)) {
+                Element encryptedAssertion = StaxParserUtil.getDOMElement(xmlEventReader);
+                response.addAssertion(new RTChoiceType(new EncryptedAssertionType(encryptedAssertion)));
+            } else
+                throw logger.parserUnknownTag(elementName, startElement.getLocation());
+        }
+
+        return response;
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#supports(QName)}
+     */
+    public boolean supports(QName qname) {
+        return JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(qname.getNamespaceURI())
+                && RESPONSE.equals(qname.getLocalPart());
+    }
+
+    /**
+     * Parse the attributes at the response element
+     *
+     * @param startElement
+     *
+     * @return
+     *
+     * @throws org.keycloak.saml.common.exceptions.ConfigurationException
+     */
+    protected StatusResponseType parseBaseAttributes(StartElement startElement) throws ParsingException {
+        ResponseType response = new ResponseType(super.parseBaseAttributes(startElement));
+        return response;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSloRequestParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSloRequestParser.java
new file mode 100755
index 0000000..0f6ba86
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSloRequestParser.java
@@ -0,0 +1,119 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.processing.core.parsers.util.SAMLParserUtil;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.protocol.LogoutRequestType;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+
+import static org.keycloak.saml.common.constants.JBossSAMLURIConstants.PROTOCOL_NSURI;
+
+/**
+ * Parse the Single Log Out requests
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Nov 3, 2010
+ */
+public class SAMLSloRequestParser extends SAMLRequestAbstractParser implements ParserNamespaceSupport {
+
+    /**
+     * @see {@link ParserNamespaceSupport#parse(XMLEventReader)}
+     */
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        // Get the startelement
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.validate(startElement, JBossSAMLConstants.LOGOUT_REQUEST.get());
+
+        LogoutRequestType logoutRequest = parseBaseAttributes(startElement);
+
+        while (xmlEventReader.hasNext()) {
+            // Let us peek at the next start element
+            startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            if (startElement == null)
+                break;
+            String elementName = StaxParserUtil.getStartElementName(startElement);
+
+            parseCommonElements(startElement, xmlEventReader, logoutRequest);
+
+            startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            if (startElement == null)
+                break;
+            elementName = StaxParserUtil.getStartElementName(startElement);
+
+            if (JBossSAMLConstants.SESSION_INDEX.get().equals(elementName)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                logoutRequest.addSessionIndex(StaxParserUtil.getElementText(xmlEventReader));
+            } else if (JBossSAMLConstants.NAMEID.get().equals(elementName)) {
+                NameIDType nameID = SAMLParserUtil.parseNameIDType(xmlEventReader);
+                logoutRequest.setNameID(nameID);
+            } else if (JBossSAMLConstants.ISSUER.get().equals(elementName)) {
+                continue;
+            } else if (JBossSAMLConstants.SIGNATURE.get().equals(elementName)) {
+                continue;
+            } else
+                throw logger.parserUnknownTag(elementName, startElement.getLocation());
+        }
+        return logoutRequest;
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#supports(QName)}
+     */
+    public boolean supports(QName qname) {
+        return PROTOCOL_NSURI.get().equals(qname.getNamespaceURI()) && JBossSAMLConstants.LOGOUT_REQUEST.equals(qname.getLocalPart());
+    }
+
+    /**
+     * Parse the attributes at the log out request element
+     *
+     * @param startElement
+     *
+     * @return
+     *
+     * @throws ParsingException
+     */
+    private LogoutRequestType parseBaseAttributes(StartElement startElement) throws ParsingException {
+        super.parseRequiredAttributes(startElement);
+        LogoutRequestType logoutRequest = new LogoutRequestType(id, issueInstant);
+        // Let us get the attributes
+        super.parseBaseAttributes(startElement, logoutRequest);
+
+        Attribute reason = startElement.getAttributeByName(new QName(JBossSAMLConstants.REASON.get()));
+        if (reason != null)
+            logoutRequest.setReason(StaxParserUtil.getAttributeValue(reason));
+
+        Attribute notOnOrAfter = startElement.getAttributeByName(new QName(JBossSAMLConstants.NOT_ON_OR_AFTER.get()));
+        if (notOnOrAfter != null)
+            logoutRequest.setNotOnOrAfter(XMLTimeUtil.parse(StaxParserUtil.getAttributeValue(notOnOrAfter)));
+        return logoutRequest;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSloResponseParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSloResponseParser.java
new file mode 100755
index 0000000..60216f7
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSloResponseParser.java
@@ -0,0 +1,78 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.StartElement;
+
+import static org.keycloak.saml.common.constants.JBossSAMLConstants.LOGOUT_RESPONSE;
+
+/**
+ * Parse the SLO Response
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Nov 3, 2010
+ */
+public class SAMLSloResponseParser extends SAMLStatusResponseTypeParser implements ParserNamespaceSupport {
+
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        // Get the startelement
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.validate(startElement, LOGOUT_RESPONSE.get());
+
+        StatusResponseType response = parseBaseAttributes(startElement);
+
+        while (xmlEventReader.hasNext()) {
+            // Let us peek at the next start element
+            startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            if (startElement == null)
+                break;
+            String elementName = StaxParserUtil.getStartElementName(startElement);
+
+            if (JBossSAMLConstants.ISSUER.get().equals(elementName)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                NameIDType issuer = new NameIDType();
+                issuer.setValue(StaxParserUtil.getElementText(xmlEventReader));
+                response.setIssuer(issuer);
+            } else if (JBossSAMLConstants.SIGNATURE.get().equals(elementName)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                StaxParserUtil.bypassElementBlock(xmlEventReader, JBossSAMLConstants.SIGNATURE.get());
+            } else if (JBossSAMLConstants.STATUS.get().equals(elementName)) {
+                response.setStatus(parseStatus(xmlEventReader));
+            }
+        }
+        return response;
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#supports(QName)}
+     */
+    public boolean supports(QName qname) {
+        return JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(qname.getNamespaceURI())
+                && LOGOUT_RESPONSE.equals(qname.getLocalPart());
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLStatusResponseTypeParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLStatusResponseTypeParser.java
new file mode 100755
index 0000000..ab4b88e
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLStatusResponseTypeParser.java
@@ -0,0 +1,187 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.common.util.StringUtil;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v2.protocol.StatusCodeType;
+import org.keycloak.dom.saml.v2.protocol.StatusDetailType;
+import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+import org.keycloak.dom.saml.v2.protocol.StatusType;
+import org.w3c.dom.Element;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import java.net.URI;
+
+/**
+ * Base Class for all Response Type parsing for SAML2
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Nov 2, 2010
+ */
+public abstract class SAMLStatusResponseTypeParser {
+
+    protected static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * Parse the attributes that are common to all SAML Response Types
+     *
+     * @param startElement
+     * @param response
+     *
+     * @throws org.keycloak.saml.common.exceptions.ParsingException
+     */
+    protected StatusResponseType parseBaseAttributes(StartElement startElement) throws ParsingException {
+        Attribute idAttr = startElement.getAttributeByName(new QName(JBossSAMLConstants.ID.get()));
+        if (idAttr == null)
+            throw logger.parserRequiredAttribute("ID");
+        String id = StaxParserUtil.getAttributeValue(idAttr);
+
+        Attribute version = startElement.getAttributeByName(new QName(JBossSAMLConstants.VERSION.get()));
+        if (version == null)
+            throw logger.parserRequiredAttribute("Version");
+
+        StringUtil.match(JBossSAMLConstants.VERSION_2_0.get(), StaxParserUtil.getAttributeValue(version));
+
+        Attribute issueInstant = startElement.getAttributeByName(new QName(JBossSAMLConstants.ISSUE_INSTANT.get()));
+        if (issueInstant == null)
+            throw logger.parserRequiredAttribute("IssueInstant");
+        XMLGregorianCalendar issueInstantVal = XMLTimeUtil.parse(StaxParserUtil.getAttributeValue(issueInstant));
+
+        StatusResponseType response = new StatusResponseType(id, issueInstantVal);
+
+        Attribute destination = startElement.getAttributeByName(new QName(JBossSAMLConstants.DESTINATION.get()));
+        if (destination != null)
+            response.setDestination(StaxParserUtil.getAttributeValue(destination));
+
+        Attribute consent = startElement.getAttributeByName(new QName(JBossSAMLConstants.CONSENT.get()));
+        if (consent != null)
+            response.setConsent(StaxParserUtil.getAttributeValue(consent));
+
+        Attribute inResponseTo = startElement.getAttributeByName(new QName(JBossSAMLConstants.IN_RESPONSE_TO.get()));
+        if (inResponseTo != null)
+            response.setInResponseTo(StaxParserUtil.getAttributeValue(inResponseTo));
+        return response;
+    }
+
+    /**
+     * Parse the status element
+     *
+     * @param xmlEventReader
+     *
+     * @return
+     *
+     * @throws ParsingException
+     */
+    protected StatusType parseStatus(XMLEventReader xmlEventReader) throws ParsingException {
+        // Get the Start Element
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        String STATUS = JBossSAMLConstants.STATUS.get();
+        StaxParserUtil.validate(startElement, STATUS);
+
+        StatusType status = new StatusType();
+
+        while (xmlEventReader.hasNext()) {
+            startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+
+            if (startElement == null)
+                break;
+
+            QName startElementName = startElement.getName();
+            String elementTag = startElementName.getLocalPart();
+
+            StatusCodeType statusCode = new StatusCodeType();
+
+            if (JBossSAMLConstants.STATUS_CODE.get().equals(elementTag)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                if (startElement == null)
+                    break;
+                Attribute valueAttr = startElement.getAttributeByName(new QName("Value"));
+                if (valueAttr != null) {
+                    statusCode.setValue(URI.create(StaxParserUtil.getAttributeValue(valueAttr)));
+                }
+                status.setStatusCode(statusCode);
+
+                // Peek at the next start element to see if it is status code
+                startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+                if (startElement == null) {
+                    // Go to Status code end element.
+                    EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
+                    if (endElement != null) {
+                        StaxParserUtil.validate(endElement, JBossSAMLConstants.STATUS_CODE.get());
+                    }
+                    continue;
+                }
+                elementTag = startElement.getName().getLocalPart();
+                if (JBossSAMLConstants.STATUS_CODE.get().equals(elementTag)) {
+                    StatusCodeType subStatusCodeType = new StatusCodeType();
+                    startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                    Attribute subValueAttr = startElement.getAttributeByName(new QName("Value"));
+                    if (subValueAttr != null) {
+                        subStatusCodeType.setValue(URI.create(StaxParserUtil.getAttributeValue(subValueAttr)));
+                    }
+                    statusCode.setStatusCode(subStatusCodeType);
+
+                    // Go to Status code end element.
+                    EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
+                    StaxParserUtil.validate(endElement, JBossSAMLConstants.STATUS_CODE.get());
+                    continue;
+                }
+            }
+            if (JBossSAMLConstants.STATUS_MESSAGE.get().equals(elementTag)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                if (startElement == null)
+                    break;
+                status.setStatusMessage(StaxParserUtil.getElementText(xmlEventReader));
+            }
+
+            if (JBossSAMLConstants.STATUS_DETAIL.get().equals(elementTag)) {
+                startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                if (startElement == null)
+                    break;
+                Element domElement = StaxParserUtil.getDOMElement(xmlEventReader);
+                StatusDetailType statusDetailType = new StatusDetailType();
+                statusDetailType.addStatusDetail(domElement);
+                status.setStatusDetail(statusDetailType);
+            }
+
+            // Get the next end element
+            XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
+            if (xmlEvent instanceof EndElement) {
+                EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
+                if (StaxParserUtil.matches(endElement, STATUS))
+                    break;
+                else
+                    throw logger.parserUnknownEndElement(StaxParserUtil.getEndElementName(endElement));
+            } else
+                break;
+        }
+        return status;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSubjectParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSubjectParser.java
new file mode 100755
index 0000000..8d676c4
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSubjectParser.java
@@ -0,0 +1,206 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.saml;
+
+import org.keycloak.saml.common.ErrorCodes;
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.constants.WSTrustConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
+import org.keycloak.saml.common.util.StaxParserUtil;
+import org.keycloak.saml.processing.core.parsers.util.SAMLParserUtil;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v2.assertion.EncryptedElementType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.assertion.SubjectConfirmationDataType;
+import org.keycloak.dom.saml.v2.assertion.SubjectConfirmationType;
+import org.keycloak.dom.saml.v2.assertion.SubjectType;
+import org.keycloak.dom.xmlsec.w3.xmldsig.KeyInfoType;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+/**
+ * Parse the saml subject
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Oct 12, 2010
+ */
+public class SAMLSubjectParser implements ParserNamespaceSupport {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * @see {@link ParserNamespaceSupport#parse(XMLEventReader)}
+     */
+    public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
+        StaxParserUtil.getNextEvent(xmlEventReader);
+
+        SubjectType subject = new SubjectType();
+
+        // Peek at the next event
+        while (xmlEventReader.hasNext()) {
+            XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
+            if (xmlEvent instanceof EndElement) {
+                EndElement endElement = (EndElement) xmlEvent;
+                if (StaxParserUtil.matches(endElement, JBossSAMLConstants.SUBJECT.get())) {
+                    endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
+                    break;
+                } else
+                    throw logger.parserUnknownEndElement(StaxParserUtil.getEndElementName(endElement));
+            }
+
+            StartElement peekedElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            if (peekedElement == null)
+                break;
+
+            String tag = StaxParserUtil.getStartElementName(peekedElement);
+
+            if (JBossSAMLConstants.NAMEID.get().equalsIgnoreCase(tag)) {
+                NameIDType nameID = SAMLParserUtil.parseNameIDType(xmlEventReader);
+                SubjectType.STSubType subType = new SubjectType.STSubType();
+                subType.addBaseID(nameID);
+                subject.setSubType(subType);
+            } else if (JBossSAMLConstants.BASEID.get().equalsIgnoreCase(tag)) {
+                throw new ParsingException(ErrorCodes.UNSUPPORTED_TYPE + JBossSAMLConstants.BASEID.get());
+            } else if (JBossSAMLConstants.ENCRYPTED_ID.get().equals(tag)) {
+                Element domElement = StaxParserUtil.getDOMElement(xmlEventReader);
+                SubjectType.STSubType subType = new SubjectType.STSubType();
+                subType.setEncryptedID(new EncryptedElementType(domElement));
+                subject.setSubType(subType);
+            } else if (JBossSAMLConstants.SUBJECT_CONFIRMATION.get().equalsIgnoreCase(tag)) {
+                StartElement subjectConfirmationElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+                Attribute method = subjectConfirmationElement.getAttributeByName(new QName(JBossSAMLConstants.METHOD.get()));
+
+                SubjectConfirmationType subjectConfirmationType = new SubjectConfirmationType();
+
+                if (method != null) {
+                    subjectConfirmationType.setMethod(StaxParserUtil.getAttributeValue(method));
+                }
+
+                // There may be additional things under subject confirmation
+                xmlEvent = StaxParserUtil.peek(xmlEventReader);
+
+                while (xmlEventReader.hasNext()) {
+                    xmlEvent = StaxParserUtil.peek(xmlEventReader);
+
+                    if (xmlEvent instanceof EndElement) {
+                        EndElement endElement = (EndElement) xmlEvent;
+                        if (StaxParserUtil.matches(endElement, JBossSAMLConstants.SUBJECT_CONFIRMATION.get())) {
+                            StaxParserUtil.getNextEndElement(xmlEventReader);
+                            break;
+                        } else
+                            throw logger.parserUnknownEndElement(StaxParserUtil.getEndElementName(endElement));
+                    }
+
+                    peekedElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+
+                    if (peekedElement == null)
+                        break;
+
+                    String startTag = StaxParserUtil.getStartElementName(peekedElement);
+
+                    if (startTag.equals(JBossSAMLConstants.NAMEID.get())) {
+                        NameIDType nameID = SAMLParserUtil.parseNameIDType(xmlEventReader);
+                        subjectConfirmationType.setNameID(nameID);
+                    } else if (JBossSAMLConstants.BASEID.get().equalsIgnoreCase(tag)) {
+                        throw logger.unsupportedType(JBossSAMLConstants.BASEID.get());
+                    } else if (JBossSAMLConstants.ENCRYPTED_ID.get().equals(tag)) {
+                        Element domElement = StaxParserUtil.getDOMElement(xmlEventReader);
+                        subjectConfirmationType.setEncryptedID(new EncryptedElementType(domElement));
+                    } else if (startTag.equals(JBossSAMLConstants.SUBJECT_CONFIRMATION_DATA.get())) {
+                        SubjectConfirmationDataType subjectConfirmationData = parseSubjectConfirmationData(xmlEventReader);
+                        subjectConfirmationType.setSubjectConfirmationData(subjectConfirmationData);
+                    }
+                }
+
+                subject.addConfirmation(subjectConfirmationType);
+            } else
+                throw logger.parserUnknownTag(tag, peekedElement.getLocation());
+        }
+        return subject;
+    }
+
+    /**
+     * @see {@link ParserNamespaceSupport#supports(QName)}
+     */
+    public boolean supports(QName qname) {
+        String nsURI = qname.getNamespaceURI();
+        String localPart = qname.getLocalPart();
+
+        return nsURI.equals(JBossSAMLURIConstants.ASSERTION_NSURI.get()) && localPart.equals(JBossSAMLConstants.SUBJECT.get());
+    }
+
+    private SubjectConfirmationDataType parseSubjectConfirmationData(XMLEventReader xmlEventReader) throws ParsingException {
+        StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+        StaxParserUtil.validate(startElement, JBossSAMLConstants.SUBJECT_CONFIRMATION_DATA.get());
+
+        SubjectConfirmationDataType subjectConfirmationData = new SubjectConfirmationDataType();
+
+        Attribute inResponseTo = startElement.getAttributeByName(new QName(JBossSAMLConstants.IN_RESPONSE_TO.get()));
+        if (inResponseTo != null) {
+            subjectConfirmationData.setInResponseTo(StaxParserUtil.getAttributeValue(inResponseTo));
+        }
+
+        Attribute notBefore = startElement.getAttributeByName(new QName(JBossSAMLConstants.NOT_BEFORE.get()));
+        if (notBefore != null) {
+            subjectConfirmationData.setNotBefore(XMLTimeUtil.parse(StaxParserUtil.getAttributeValue(notBefore)));
+        }
+
+        Attribute notOnOrAfter = startElement.getAttributeByName(new QName(JBossSAMLConstants.NOT_ON_OR_AFTER.get()));
+        if (notOnOrAfter != null) {
+            subjectConfirmationData.setNotOnOrAfter(XMLTimeUtil.parse(StaxParserUtil.getAttributeValue(notOnOrAfter)));
+        }
+
+        Attribute recipient = startElement.getAttributeByName(new QName(JBossSAMLConstants.RECIPIENT.get()));
+        if (recipient != null) {
+            subjectConfirmationData.setRecipient(StaxParserUtil.getAttributeValue(recipient));
+        }
+
+        Attribute address = startElement.getAttributeByName(new QName(JBossSAMLConstants.ADDRESS.get()));
+        if (address != null) {
+            subjectConfirmationData.setAddress(StaxParserUtil.getAttributeValue(address));
+        }
+
+        XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
+        if (!(xmlEvent instanceof EndElement)) {
+            startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+            String tag = StaxParserUtil.getStartElementName(startElement);
+            if (tag.equals(WSTrustConstants.XMLDSig.KEYINFO)) {
+                KeyInfoType keyInfo = SAMLParserUtil.parseKeyInfo(xmlEventReader);
+                subjectConfirmationData.setAnyType(keyInfo);
+            } else if (tag.equals(WSTrustConstants.XMLEnc.ENCRYPTED_KEY)) {
+                subjectConfirmationData.setAnyType(StaxParserUtil.getDOMElement(xmlEventReader));
+            } else
+                throw logger.parserUnknownTag(tag, startElement.getLocation());
+        }
+
+        // Get the end tag
+        EndElement endElement = (EndElement) StaxParserUtil.getNextEvent(xmlEventReader);
+        StaxParserUtil.matches(endElement, JBossSAMLConstants.SUBJECT_CONFIRMATION_DATA.get());
+        return subjectConfirmationData;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SecurityActions.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SecurityActions.java
new file mode 100755
index 0000000..6ff7025
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SecurityActions.java
@@ -0,0 +1,94 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.parsers.util;
+
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Oct 25, 2010
+ */
+public class SecurityActions {
+
+    /**
+     * <p>Returns a system property value using the specified <code>key</code>. If not found the
+     * <code>defaultValue</code> will be returned.</p>
+     *
+     * @param key
+     * @param defaultValue
+     *
+     * @return
+     */
+    static String getSystemProperty(final String key, final String defaultValue) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty(key, defaultValue);
+                }
+            });
+        } else {
+            return System.getProperty(key, defaultValue);
+        }
+    }
+
+    /**
+     * Load a resource based on the passed {@link Class} classloader. Failing which try with the Thread Context CL
+     *
+     * @param clazz
+     * @param resourceName
+     *
+     * @return
+     */
+    static URL loadResource(final Class<?> clazz, final String resourceName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<URL>() {
+                public URL run() {
+                    URL url = null;
+                    ClassLoader clazzLoader = clazz.getClassLoader();
+                    url = clazzLoader.getResource(resourceName);
+
+                    if (url == null) {
+                        clazzLoader = Thread.currentThread().getContextClassLoader();
+                        url = clazzLoader.getResource(resourceName);
+                    }
+
+                    return url;
+                }
+            });
+        } else {
+            URL url = null;
+            ClassLoader clazzLoader = clazz.getClassLoader();
+            url = clazzLoader.getResource(resourceName);
+
+            if (url == null) {
+                clazzLoader = Thread.currentThread().getContextClassLoader();
+                url = clazzLoader.getResource(resourceName);
+            }
+
+            return url;
+        }
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/SAML11Constants.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/SAML11Constants.java
new file mode 100755
index 0000000..ba325c9
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/SAML11Constants.java
@@ -0,0 +1,131 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v1;
+
+/**
+ * Constants for the SAML v1.1 Specifications
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jun 22, 2011
+ */
+public interface SAML11Constants {
+
+    String ACTION = "Action";
+
+    String ASSERTIONID = "AssertionID";
+
+    String ASSERTION_11_NSURI = "urn:oasis:names:tc:SAML:1.0:assertion";
+
+    String ASSERTION_ARTIFACT = "AssertionArtifact";
+
+    String ASSERTION_ID_REF = "AssertionIDReference";
+
+    String ATTRIBUTE_QUERY = "AttributeQuery";
+
+    String ATTRIBUTE_NAME = "AttributeName";
+
+    String ATTRIBUTE_NAMESPACE = "AttributeNamespace";
+
+    String ATTRIBUTE_STATEMENT = "AttributeStatement";
+
+    String AUDIENCE_RESTRICTION_CONDITION = "AudienceRestrictionCondition";
+
+    String AUTHENTICATION_INSTANT = "AuthenticationInstant";
+
+    String AUTHENTICATION_METHOD = "AuthenticationMethod";
+
+    String AUTH_METHOD_PASSWORD = "urn:oasis:names:tc:SAML:1.0:am:password";
+
+    String AUTH_METHOD_KERBEROS = "urn:ietf:rfc:1510";
+
+    String AUTH_METHOD_SRP = "urn:ietf:rfc:2945";
+
+    String AUTH_METHOD_TLS = "urn:ietf:rfc:2246";
+
+    String AUTHENTICATION_QUERY = "AuthenticationQuery";
+
+    String AUTHENTICATION_STATEMENT = "AuthenticationStatement";
+
+    String AUTHORITY_BINDING = "AuthorityBinding";
+
+    String AUTHORITY_KIND = "AuthorityKind";
+
+    String AUTHORIZATION_DECISION_QUERY = "AuthorizationDecisionQuery";
+
+    String AUTHORIZATION_DECISION_STATEMENT = "AuthorizationDecisionStatement";
+
+    String BINDING = "Binding";
+
+    String CONFIRMATION_METHOD = "ConfirmationMethod";
+
+    String DECISION = "Decision";
+
+    String DNS_ADDRESS = "DNSAddress";
+
+    String EVIDENCE = "Evidence";
+
+    String FORMAT = "Format";
+
+    String FORMAT_EMAIL_ADDRESS = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress";
+
+    String FORMAT_UNSPECIFIED = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified";
+
+    String IN_RESPONSE_TO = "InResponseTo";
+
+    String IP_ADDRESS = "IPAddress";
+
+    String ISSUER = "Issuer";
+
+    String ISSUE_INSTANT = "IssueInstant";
+
+    String LOCATION = "Location";
+
+    String MAJOR_VERSION = "MajorVersion";
+
+    String MINOR_VERSION = "MinorVersion";
+
+    String NAME_IDENTIFIER = "NameIdentifier";
+
+    String NAME_QUALIFIER = "NameQualifier";
+
+    String NAMESPACE = "Namespace";
+
+    String PROTOCOL_11_NSURI = "urn:oasis:names:tc:SAML:1.0:protocol";
+
+    String RECIPIENT = "Recipient";
+
+    String REQUEST = "Request";
+
+    String REQUEST_ID = "RequestID";
+
+    String RESOURCE = "Resource";
+
+    String RESPONSE = "Response";
+
+    String RESPONSE_ID = "ResponseID";
+
+    String STATUS = "Status";
+
+    String STATUS_CODE = "StatusCode";
+
+    String STATUS_DETAIL = "StatusDetail";
+
+    String STATUS_MSG = "StatusMessage";
+
+    String VALUE = "Value";
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/writers/BaseSAML11Writer.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/writers/BaseSAML11Writer.java
new file mode 100755
index 0000000..2adfac7
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/writers/BaseSAML11Writer.java
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v1.writers;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+
+import javax.xml.stream.XMLStreamWriter;
+
+/**
+ * @author Anil.Saldhana@redhat.com
+ * @since Jun 27, 2011
+ */
+public abstract class BaseSAML11Writer {
+
+    protected static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    protected static String PROTOCOL_PREFIX = "samlp";
+
+    protected static String ASSERTION_PREFIX = "saml";
+
+    protected static String XACML_SAML_PREFIX = "xacml-saml";
+
+    protected static String XACML_SAML_PROTO_PREFIX = "xacml-samlp";
+
+    protected static String XSI_PREFIX = "xsi";
+
+    protected XMLStreamWriter writer;
+
+    public BaseSAML11Writer(XMLStreamWriter writer) {
+        this.writer = writer;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/writers/SAML11RequestWriter.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/writers/SAML11RequestWriter.java
new file mode 100755
index 0000000..60b4695
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/writers/SAML11RequestWriter.java
@@ -0,0 +1,171 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v1.writers;
+
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.util.StaxUtil;
+import org.keycloak.saml.processing.core.saml.v1.SAML11Constants;
+import org.keycloak.dom.saml.v1.assertion.SAML11ActionType;
+import org.keycloak.dom.saml.v1.assertion.SAML11AttributeDesignatorType;
+import org.keycloak.dom.saml.v1.assertion.SAML11AttributeType;
+import org.keycloak.dom.saml.v1.assertion.SAML11EvidenceType;
+import org.keycloak.dom.saml.v1.assertion.SAML11SubjectType;
+import org.keycloak.dom.saml.v1.protocol.SAML11AttributeQueryType;
+import org.keycloak.dom.saml.v1.protocol.SAML11AuthenticationQueryType;
+import org.keycloak.dom.saml.v1.protocol.SAML11AuthorizationDecisionQueryType;
+import org.keycloak.dom.saml.v1.protocol.SAML11QueryAbstractType;
+import org.keycloak.dom.saml.v1.protocol.SAML11RequestType;
+
+import javax.xml.stream.XMLStreamWriter;
+import java.net.URI;
+import java.util.List;
+
+/**
+ * Write the {@link org.keycloak.dom.saml.v1.protocol.SAML11RequestType} to stream
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jun 27, 2011
+ */
+public class SAML11RequestWriter extends BaseSAML11Writer {
+
+    protected String namespace = SAML11Constants.PROTOCOL_11_NSURI;
+
+    protected SAML11AssertionWriter assertionWriter;
+
+    public SAML11RequestWriter(XMLStreamWriter writer) {
+        super(writer);
+        assertionWriter = new SAML11AssertionWriter(writer);
+    }
+
+    public void write(SAML11RequestType request) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, SAML11Constants.REQUEST, namespace);
+        StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, namespace);
+        StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, SAML11Constants.ASSERTION_11_NSURI);
+        StaxUtil.writeDefaultNameSpace(writer, namespace);
+
+        // Attributes
+        StaxUtil.writeAttribute(writer, SAML11Constants.REQUEST_ID, request.getID());
+        StaxUtil.writeAttribute(writer, SAML11Constants.MAJOR_VERSION, request.getMajorVersion() + "");
+        StaxUtil.writeAttribute(writer, SAML11Constants.MINOR_VERSION, request.getMinorVersion() + "");
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ISSUE_INSTANT.get(), request.getIssueInstant().toString());
+
+        List<String> assertionIDRefs = request.getAssertionIDRef();
+        for (String assertionIDRef : assertionIDRefs) {
+            StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, SAML11Constants.ASSERTION_ID_REF,
+                    SAML11Constants.ASSERTION_11_NSURI);
+            StaxUtil.writeCharacters(writer, assertionIDRef);
+            StaxUtil.writeEndElement(writer);
+        }
+
+        List<String> assertionArtifacts = request.getAssertionArtifact();
+        for (String assertionArtifact : assertionArtifacts) {
+            StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, SAML11Constants.ASSERTION_ARTIFACT, namespace);
+            StaxUtil.writeCharacters(writer, assertionArtifact);
+            StaxUtil.writeEndElement(writer);
+        }
+
+        SAML11QueryAbstractType query = request.getQuery();
+        if (query instanceof SAML11AuthenticationQueryType) {
+            SAML11AuthenticationQueryType authQuery = (SAML11AuthenticationQueryType) query;
+            write(authQuery);
+        } else if (query instanceof SAML11AttributeQueryType) {
+            SAML11AttributeQueryType attQuery = (SAML11AttributeQueryType) query;
+            write(attQuery);
+        } else if (query instanceof SAML11AuthenticationQueryType) {
+            SAML11AuthenticationQueryType attQuery = (SAML11AuthenticationQueryType) query;
+            write(attQuery);
+        } else if (query instanceof SAML11AuthorizationDecisionQueryType) {
+            SAML11AuthorizationDecisionQueryType attQuery = (SAML11AuthorizationDecisionQueryType) query;
+            write(attQuery);
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    public void write(SAML11AuthenticationQueryType auth) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, SAML11Constants.AUTHENTICATION_QUERY, namespace);
+
+        URI authMethod = auth.getAuthenticationMethod();
+        if (authMethod != null) {
+            StaxUtil.writeAttribute(writer, SAML11Constants.AUTHENTICATION_METHOD, authMethod.toString());
+        }
+
+        SAML11SubjectType subject = auth.getSubject();
+        if (subject != null) {
+            assertionWriter.write(subject);
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    public void write(SAML11AttributeQueryType attr) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, SAML11Constants.ATTRIBUTE_QUERY, namespace);
+
+        URI resource = attr.getResource();
+        if (resource != null) {
+            StaxUtil.writeAttribute(writer, SAML11Constants.RESOURCE, resource.toString());
+        }
+
+        SAML11SubjectType subject = attr.getSubject();
+        if (subject != null) {
+            assertionWriter.write(subject);
+        }
+
+        List<SAML11AttributeDesignatorType> attributes = attr.get();
+        for (SAML11AttributeDesignatorType attribute : attributes) {
+            if (attribute instanceof SAML11AttributeType) {
+                SAML11AttributeType sat = (SAML11AttributeType) attribute;
+                assertionWriter.write(sat);
+            } else
+                throw logger.writerUnknownTypeError(attribute.getClass().getName());
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    public void write(SAML11AuthorizationDecisionQueryType attr) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, SAML11Constants.AUTHORIZATION_DECISION_QUERY, namespace);
+
+        URI resource = attr.getResource();
+        if (resource != null) {
+            StaxUtil.writeAttribute(writer, SAML11Constants.RESOURCE, resource.toString());
+        }
+
+        SAML11SubjectType subject = attr.getSubject();
+        if (subject != null) {
+            assertionWriter.write(subject);
+        }
+
+        List<SAML11ActionType> actions = attr.get();
+        for (SAML11ActionType action : actions) {
+            assertionWriter.write(action);
+        }
+
+        SAML11EvidenceType evidence = attr.getEvidence();
+        if (evidence != null) {
+            assertionWriter.write(evidence);
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/writers/SAML11ResponseWriter.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/writers/SAML11ResponseWriter.java
new file mode 100755
index 0000000..7e6f6fd
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v1/writers/SAML11ResponseWriter.java
@@ -0,0 +1,137 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v1.writers;
+
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.util.StaxUtil;
+import org.keycloak.saml.common.util.StringUtil;
+import org.keycloak.saml.processing.core.saml.v1.SAML11Constants;
+import org.keycloak.dom.saml.common.CommonStatusDetailType;
+import org.keycloak.dom.saml.v1.assertion.SAML11AssertionType;
+import org.keycloak.dom.saml.v1.protocol.SAML11ResponseType;
+import org.keycloak.dom.saml.v1.protocol.SAML11StatusCodeType;
+import org.keycloak.dom.saml.v1.protocol.SAML11StatusType;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamWriter;
+import java.net.URI;
+import java.util.List;
+
+/**
+ * Write the {@link SAML11ResponseType} to stream
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jun 29, 2011
+ */
+public class SAML11ResponseWriter extends BaseSAML11Writer {
+
+    protected String namespace = SAML11Constants.PROTOCOL_11_NSURI;
+
+    protected SAML11AssertionWriter assertionWriter;
+
+    public SAML11ResponseWriter(XMLStreamWriter writer) {
+        super(writer);
+        assertionWriter = new SAML11AssertionWriter(writer);
+    }
+
+    public void write(SAML11ResponseType response) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, SAML11Constants.RESPONSE, namespace);
+        StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, namespace);
+        StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, SAML11Constants.ASSERTION_11_NSURI);
+
+        // Attributes
+        StaxUtil.writeAttribute(writer, SAML11Constants.RESPONSE_ID, response.getID());
+        StaxUtil.writeAttribute(writer, SAML11Constants.MAJOR_VERSION, response.getMajorVersion() + "");
+        StaxUtil.writeAttribute(writer, SAML11Constants.MINOR_VERSION, response.getMinorVersion() + "");
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ISSUE_INSTANT.get(), response.getIssueInstant().toString());
+        String inResp = response.getInResponseTo();
+        if (StringUtil.isNotNull(inResp)) {
+            StaxUtil.writeAttribute(writer, SAML11Constants.IN_RESPONSE_TO, inResp);
+        }
+
+        URI recipient = response.getRecipient();
+        if (recipient != null) {
+            StaxUtil.writeAttribute(writer, SAML11Constants.RECIPIENT, recipient.toString());
+        }
+
+        Element sig = response.getSignature();
+        if (sig != null) {
+            StaxUtil.writeDOMElement(writer, sig);
+        }
+
+        SAML11StatusType status = response.getStatus();
+        if (status != null) {
+            write(status);
+        }
+
+        List<SAML11AssertionType> assertions = response.get();
+        for (SAML11AssertionType assertion : assertions) {
+            assertionWriter.write(assertion);
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    public void write(SAML11StatusType status) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, SAML11Constants.STATUS, namespace);
+
+        SAML11StatusCodeType statusCode = status.getStatusCode();
+        if (statusCode != null) {
+            write(statusCode);
+        }
+
+        String statusMsg = status.getStatusMessage();
+        if (StringUtil.isNotNull(statusMsg)) {
+            StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, SAML11Constants.STATUS_MSG, namespace);
+            StaxUtil.writeCharacters(writer, statusMsg);
+            StaxUtil.writeEndElement(writer);
+        }
+
+        CommonStatusDetailType details = status.getStatusDetail();
+        if (details != null) {
+            StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, SAML11Constants.STATUS_DETAIL, namespace);
+            List<Object> objs = details.getAny();
+            for (Object theObj : objs) {
+                StaxUtil.writeCharacters(writer, theObj.toString());
+            }
+            StaxUtil.writeEndElement(writer);
+        }
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    public void write(SAML11StatusCodeType statusCode) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, SAML11Constants.STATUS_CODE, namespace);
+
+        QName value = statusCode.getValue();
+        if (value == null)
+            throw logger.writerNullValueError("Attribute Value");
+        StaxUtil.writeAttribute(writer, SAML11Constants.VALUE, value);
+
+        SAML11StatusCodeType secondCode = statusCode.getStatusCode();
+        if (secondCode != null) {
+            write(secondCode);
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/common/IDGenerator.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/common/IDGenerator.java
new file mode 100755
index 0000000..bd0248a
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/common/IDGenerator.java
@@ -0,0 +1,58 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.common;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+
+import java.util.UUID;
+
+/**
+ * Utility class that generates unique IDs
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jan 5, 2009
+ */
+public class IDGenerator {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /*
+     * Create a basic unique ID
+     */
+    public static String create() {
+        return UUID.randomUUID().toString();
+    }
+
+    /**
+     * Create an id that is prefixed by a string
+     *
+     * @param prefix
+     *
+     * @return an id
+     *
+     * @throws IllegalArgumentException when prefix is null
+     */
+    public static String create(String prefix) {
+        if (prefix == null)
+            throw logger.nullArgumentError("prefix");
+        StringBuilder sb = new StringBuilder(prefix);
+        sb.append(IDGenerator.create());
+        return sb.toString();
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/common/SAMLDocumentHolder.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/common/SAMLDocumentHolder.java
new file mode 100755
index 0000000..30bef07
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/common/SAMLDocumentHolder.java
@@ -0,0 +1,64 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.common;
+
+import org.keycloak.dom.saml.v2.SAML2Object;
+import org.w3c.dom.Document;
+
+/**
+ * A Holder class that can store the SAML object as well as the corresponding DOM object.
+ *
+ * Users of this class need to make it threadsafe by having one instance per thread (ThreadLocal)
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Aug 13, 2009
+ */
+public class SAMLDocumentHolder {
+
+    private SAML2Object samlObject;
+    private Document samlDocument;
+
+    public SAMLDocumentHolder(SAML2Object samlObject) {
+        this.samlObject = samlObject;
+    }
+
+    public SAMLDocumentHolder(Document samlDocument) {
+        this.samlDocument = samlDocument;
+    }
+
+    public SAMLDocumentHolder(SAML2Object samlObject, Document samlDocument) {
+        this.samlObject = samlObject;
+        this.samlDocument = samlDocument;
+    }
+
+    public SAML2Object getSamlObject() {
+        return samlObject;
+    }
+
+    public void setSamlObject(SAML2Object samlObject) {
+        this.samlObject = samlObject;
+    }
+
+    public Document getSamlDocument() {
+        return samlDocument;
+    }
+
+    public void setSamlDocument(Document samlDocument) {
+        this.samlDocument = samlDocument;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/constants/X500SAMLProfileConstants.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/constants/X500SAMLProfileConstants.java
new file mode 100755
index 0000000..3712f53
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/constants/X500SAMLProfileConstants.java
@@ -0,0 +1,154 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.constants;
+
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * X500 SAML Profile Constants Adapted from
+ * http://code.google.com/p/simplesamlphp/source/browse/trunk/attributemap/name2oid.php?r=2654
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Sep 11, 2009
+ */
+public enum X500SAMLProfileConstants {
+    A_RECORD("aRecord", "urn:oid:0.9.2342.19200300.100.1.26"), ALIASED_ENTRY_NAME("aliasedEntryName", "urn:oid:2.5.4.1"), ALIASED_OBJECT_NAME(
+            "aliasedObjectName", "urn:oid:2.5.4.1"), ASSOCIATED_DOMAIN("associatedDomain", "urn:oid:0.9.2342.19200300.100.1.37"), ASSOCIATED_NAME(
+            "associatedName", "urn:oid:0.9.2342.19200300.100.1.38"), AUDIO("audio", "urn:oid:0.9.2342.19200300.100.1.55"), AUTHORITY_REVOCATION_LIST(
+            "authorityRevocationList", "urn:oid:2.5.4.38"), BINDING_NAME("buildingName", "urn:oid:0.9.2342.19200300.100.1.48"), BUSINESS_CATEGORY(
+            "businessCategory", "urn:oid:2.5.4.15"), C("c", "urn:oid:2.5.4.6"), CA_CERTIFICATE("cACertificate",
+            "urn:oid:2.5.4.37"), CNAME_RECORD("cNAMERecord", "urn:oid:0.9.2342.19200300.100.1.31"), CAR_LICENSE("carLicense",
+            "urn:oid:2.16.840.1.113730.3.1.1"), CRL("certificateRevocationList", "urn:oid:2.5.4.39"), CN("cn",
+            "urn:oid:2.5.4.3"), CO("co", "urn:oid:0.9.2342.19200300.100.1.43"), COMMON_NAME("commonName", "urn:oid:2.5.4.3"), COUNTRY_NAME(
+            "countryName", "urn:oid:2.5.4.6"), CROSS_CERTIFICATE_PAIR("crossCertificatePair", "urn:oid:2.5.4.40"), D_IT_REDIRECT(
+            "dITRedirect", "urn:oid:0.9.2342.19200300.100.1.54"), D_SA_QUALITY("dSAQuality",
+            "urn:oid:0.9.2342.19200300.100.1.49"), DC("dc", "urn:oid:0.9.2342.19200300.100.1.25"), DELTA_REVOCATION_LIST(
+            "deltaRevocationList", "urn:oid:2.5.4.53"), DEPARTMENT_NUMBER("departmentNumber", "urn:oid:2.16.840.1.113730.3.1.2"), DESCRIPTION(
+            "description", "urn:oid:2.5.4.13"), DESTINATION_INDICATOR("destinationIndicator", "urn:oid:2.5.4.27"), DISPLAY_NAME(
+            "displayName", "urn:oid:2.16.840.1.113730.3.1.241"), DISTINGUISHED_NAME("distinguishedName", "urn:oid:2.5.4.49"), DMD_NAME(
+            "dmdName", "urn:oid:2.5.4.54"), DN_QUALIFIER("dnQualifier", "urn:oid:2.5.4.46"), DOCUMENT_AUTHOR("documentAuthor",
+            "urn:oid:0.9.2342.19200300.100.1.14"), DOCUMENT_IDENTIFIER("documentIdentifier",
+            "urn:oid:0.9.2342.19200300.100.1.11"), DOCUMENT_LOCATION("documentLocation", "urn:oid:0.9.2342.19200300.100.1.15"), DOCUMENT_PUBLISHER(
+            "documentPublisher", "urn:oid:0.9.2342.19200300.100.1.56"), DOCUMENT_TITLE("documentTitle",
+            "urn:oid:0.9.2342.19200300.100.1.12"), DOCUMENT_VERSION("documentVersion", "urn:oid:0.9.2342.19200300.100.1.13"), DOMAIN_COMPONENT(
+            "domainComponent", "urn:oid:0.9.2342.19200300.100.1.25"), DRINK("drink", "urn:oid:0.9.2342.19200300.100.1.5"), EDU_ORG_HOMEPAGEURI(
+            "eduOrgHomePageURI", "urn:oid:1.3.6.1.4.1.5923.1.2.1.2"), EDU_ORG_IDENTITY_AUTHN_POLICYURI(
+            "eduOrgIdentityAuthNPolicyURI", "urn:oid:1.3.6.1.4.1.5923.1.2.1.3"), EDU_ORG_LEGALNAME("eduOrgLegalName",
+            "urn:oid:1.3.6.1.4.1.5923.1.2.1.4"), EDU_ORG_SUPERIORURI("eduOrgSuperiorURI", "urn:oid:1.3.6.1.4.1.5923.1.2.1.5"), EDU_ORG_WHITEPAGESURI(
+            "eduOrgWhitePagesURI", "urn:oid:1.3.6.1.4.1.5923.1.2.1.6"), EDU_PERSON_AFFLIATION("eduPersonAffiliation",
+            "urn:oid:1.3.6.1.4.1.5923.1.1.1.1"), EDU_PERSON_ENTITLEMENT("eduPersonEntitlement",
+            "urn:oid:1.3.6.1.4.1.5923.1.1.1.7"), EDU_PERSON_NICKNAME("eduPersonNickname", "urn:oid:1.3.6.1.4.1.5923.1.1.1.2"), EDU_PERSON_ORG_DN(
+            "eduPersonOrgDN", "urn:oid:1.3.6.1.4.1.5923.1.1.1.3"), EDU_PERSION_ORG_UNIT_DN("eduPersonOrgUnitDN",
+            "urn:oid:1.3.6.1.4.1.5923.1.1.1.4"), EDU_PERSON_PRIMARY_AFFLIATION("eduPersonPrimaryAffiliation",
+            "urn:oid:1.3.6.1.4.1.5923.1.1.1.5"), EDU_PERSON_PRIMARY_ORG_UNIT_DN("eduPersonPrimaryOrgUnitDN",
+            "urn:oid:1.3.6.1.4.1.5923.1.1.1.8"), EDU_PERSON_PRINCIPAL_NAME("eduPersonPrincipalName",
+            "urn:oid:1.3.6.1.4.1.5923.1.1.1.6"), EDU_PERSON_SCOPED_AFFLIATION("eduPersonScopedAffiliation",
+            "urn:oid:1.3.6.1.4.1.5923.1.1.1.9"), EDU_PERSON_TARGETED_ID("eduPersonTargetedID",
+            "urn:oid:1.3.6.1.4.1.5923.1.1.1.10"), EMAIL("email", "urn:oid:1.2.840.113549.1.9.1"), EMAIL_ADDRESS("emailAddress",
+            "urn:oid:1.2.840.113549.1.9.1"), EMPLOYEE_NUMBER("employeeNumber", "urn:oid:2.16.840.1.113730.3.1.3"), EMPLOYEE_TYPE(
+            "employeeType", "urn:oid:2.16.840.1.113730.3.1.4"), ENHANCED_SEARCH_GUIDE("enhancedSearchGuide", "urn:oid:2.5.4.47"), FAX_TELEPHONE_NUMBER(
+            "facsimileTelephoneNumber", "urn:oid:2.5.4.23"), FAVORITE_DRINK("favouriteDrink",
+            "urn:oid:0.9.2342.19200300.100.1.5"), FAX("fax", "urn:oid:2.5.4.23"), FEDERATION_FEIDE_SCHEMA_VERSION(
+            "federationFeideSchemaVersion", "urn:oid:1.3.6.1.4.1.2428.90.1.9"), FRIENDLY_COUNTRY_NAME("friendlyCountryName",
+            "urn:oid:0.9.2342.19200300.100.1.43"), GENERATION_QUALIFIER("generationQualifier", "urn:oid:2.5.4.44"), GIVEN_NAME(
+            "givenName", "urn:oid:2.5.4.42"), GN("gn", "urn:oid:2.5.4.42"), HOME_PHONE("homePhone",
+            "urn:oid:0.9.2342.19200300.100.1.20"), HOME_POSTAL_ADDRESS("homePostalAddress",
+            "urn:oid:0.9.2342.19200300.100.1.39"), HOME_TELEPHONE_NUMBER("homeTelephoneNumber",
+            "urn:oid:0.9.2342.19200300.100.1.20"), HOST("host", "urn:oid:0.9.2342.19200300.100.1.9"), HOUSE_IDENTIFIER(
+            "houseIdentifier", "urn:oid:2.5.4.51"), INFO("info", "urn:oid:0.9.2342.19200300.100.1.4"), INITIALS("initials",
+            "urn:oid:2.5.4.43"), INTERNATIONAL_ISDN_NUMBER("internationaliSDNNumber", "urn:oid:2.5.4.25"), IS_MEMBEROF(
+            "isMemberOf", "urn:oid:1.3.6.1.4.1.5923.1.5.1.1"), JANET_MAILBOX("janetMailbox",
+            "urn:oid:0.9.2342.19200300.100.1.46"), JPEG_PHOTO("jpegPhoto", "urn:oid:0.9.2342.19200300.100.1.60"), KNOWLEDGE_INFORMATION(
+            "knowledgeInformation", "urn:oid:2.5.4.2"), L("l", "urn:oid:2.5.4.7"), LABELED_URI("labeledURI",
+            "urn:oid:1.3.6.1.4.1.250.1.57"), LOCALITY_NAME("localityName", "urn:oid:2.5.4.7"), M_DRECORD("mDRecord",
+            "urn:oid:0.9.2342.19200300.100.1.27"), M_XRECORD("mXRecord", "urn:oid:0.9.2342.19200300.100.1.28"), MAIL("mail",
+            "urn:oid:0.9.2342.19200300.100.1.3"), MAIL_PREFERENCEOPTION("mailPreferenceOption",
+            "urn:oid:0.9.2342.19200300.100.1.47"), MANAGER("manager", "urn:oid:0.9.2342.19200300.100.1.10"), MEMBER("member",
+            "urn:oid:2.5.4.31"), MOBILE("mobile", "urn:oid:0.9.2342.19200300.100.1.41"), MOBILE_TELEPHONE_NUMBER(
+            "mobileTelephoneNumber", "urn:oid:0.9.2342.19200300.100.1.41"), N_SRECORD("nSRecord",
+            "urn:oid:0.9.2342.19200300.100.1.29"), NAME("name", "urn:oid:2.5.4.41"), NOR_EDU_ORG_ACRONYM("norEduOrgAcronym",
+            "urn:oid:1.3.6.1.4.1.2428.90.1.6"), NOR_EDU_ORG_NIN("norEduOrgNIN", "urn:oid:1.3.6.1.4.1.2428.90.1.12"), NOR_EDU_ORG_SCHEMA_VERSION(
+            "norEduOrgSchemaVersion", "urn:oid:1.3.6.1.4.1.2428.90.1.11"), NOR_EDU_ORG_UNIQUE_IDENTIFIER(
+            "norEduOrgUniqueIdentifier", "urn:oid:1.3.6.1.4.1.2428.90.1.7"), NOR_EDU_ORG_UNIQUE_NUMBER("norEduOrgUniqueNumber",
+            "urn:oid:1.3.6.1.4.1.2428.90.1.1"), NOR_EDU_ORG_UNIT_UNIQUE_IDENTIFIER("norEduOrgUnitUniqueIdentifier",
+            "urn:oid:1.3.6.1.4.1.2428.90.1.8"), NOR_EDU_ORG_UNIT_UNIQUE_NUMBER("norEduOrgUnitUniqueNumber",
+            "urn:oid:1.3.6.1.4.1.2428.90.1.2"), NOR_EDU_PERSON_BIRTH_DATE("norEduPersonBirthDate",
+            "urn:oid:1.3.6.1.4.1.2428.90.1.3"), NOR_EDU_PERSON_LIN("norEduPersonLIN", "urn:oid:1.3.6.1.4.1.2428.90.1.4"), NOR_EDU_PERSON_NIN(
+            "norEduPersonNIN", "urn:oid:1.3.6.1.4.1.2428.90.1.5"), O("o", "urn:oid:2.5.4.10"), OBJECT_CLASS("objectClass",
+            "urn:oid:2.5.4.0"), ORGANIZATION_NAME("organizationName", "urn:oid:2.5.4.10"), ORGANIZATIONAL_STATUS(
+            "organizationalStatus", "urn:oid:0.9.2342.19200300.100.1.45"), ORGANIZATIONAL_UNIT_NAME("organizationalUnitName",
+            "urn:oid:2.5.4.11"), OTHER_MAIL_BOX("otherMailbox", "urn:oid:0.9.2342.19200300.100.1.22"), OU("ou",
+            "urn:oid:2.5.4.11"), OWNER("owner", "urn:oid:2.5.4.32"), PAGER("pager", "urn:oid:0.9.2342.19200300.100.1.42"), PAGER_TELEPHONE_NUMBER(
+            "pagerTelephoneNumber", "urn:oid:0.9.2342.19200300.100.1.42"), PERSONAL_SIGNATURE("personalSignature",
+            "urn:oid:0.9.2342.19200300.100.1.53"), PERSONAL_TITLE("personalTitle", "urn:oid:0.9.2342.19200300.100.1.40"), PHOTO(
+            "photo", "urn:oid:0.9.2342.19200300.100.1.7"), PHYSICAL_DELIVERY_OFFICE_NAME("physicalDeliveryOfficeName",
+            "urn:oid:2.5.4.19"), PKCS_9_EMAIL("pkcs9email", "urn:oid:1.2.840.113549.1.9.1"), POST_OFFICE_BOX("postOfficeBox",
+            "urn:oid:2.5.4.18"), POSTAL_ADDRESS("postalAddress", "urn:oid:2.5.4.16"), POSTAL_CODE("postalCode",
+            "urn:oid:2.5.4.17"), PREFERRED_DELIVERY_METHOD("preferredDeliveryMethod", "urn:oid:2.5.4.28"), PREFERRED_LANGUAGE(
+            "preferredLanguage", "urn:oid:2.16.840.1.113730.3.1.39"), PRESENTATION_ADDRESS("presentationAddress",
+            "urn:oid:2.5.4.29"), PROTOCOL_INFORMATION("protocolInformation", "urn:oid:2.5.4.48"), PSEUDONYM("pseudonym",
+            "urn:oid:2.5.4.65"), REGISTERED_ADDRESS("registeredAddress", "urn:oid:2.5.4.26"), RFC_822_MAILBOX("rfc822Mailbox",
+            "urn:oid:0.9.2342.19200300.100.1.3"), ROLE_OCCUPANT("roleOccupant", "urn:oid:2.5.4.33"), ROOM_NUMBER("roomNumber",
+            "urn:oid:0.9.2342.19200300.100.1.6"), S_OAR_RECORD("sOARecord", "urn:oid:0.9.2342.19200300.100.1.30"), SEARCH_GUIDE(
+            "searchGuide", "urn:oid:2.5.4.14"), SECRETARY("secretary", "urn:oid:0.9.2342.19200300.100.1.21"), SEE_ALSO(
+            "seeAlso", "urn:oid:2.5.4.34"), SERIAL_NUMBER("serialNumber", "urn:oid:2.5.4.5"), SINGLE_LEVEL_QUALITY(
+            "singleLevelQuality", "urn:oid:0.9.2342.19200300.100.1.50"), SN("sn", "urn:oid:2.5.4.4"), ST("st",
+            "urn:oid:2.5.4.8"), STATE_OR_PROVINCE_NAME("stateOrProvinceName", "urn:oid:2.5.4.8"), STREET("street",
+            "urn:oid:2.5.4.9"), STREET_ADDRESS("streetAddress", "urn:oid:2.5.4.9"), SUBTREE_MAXIMUM_QUALITY(
+            "subtreeMaximumQuality", "urn:oid:0.9.2342.19200300.100.1.52"), SUBTREE_MINIMUM_QUALITY("subtreeMinimumQuality",
+            "urn:oid:0.9.2342.19200300.100.1.51"), SUPPORTED_ALGORITHMS("supportedAlgorithms", "urn:oid:2.5.4.52"), SUPPORTED_APPLICATION_CONTEXT(
+            "supportedApplicationContext", "urn:oid:2.5.4.30"), SURNAME("surname", "urn:oid:2.5.4.4"), TELEPHONE_NUMBER(
+            "telephoneNumber", "urn:oid:2.5.4.20"), TELETEX_TERMINAL_IDENTIFIER("teletexTerminalIdentifier", "urn:oid:2.5.4.22"), TELEX_NUMBER(
+            "telexNumber", "urn:oid:2.5.4.21"), TEXT_ENCODED_OR_ADDRESS("textEncodedORAddress",
+            "urn:oid:0.9.2342.19200300.100.1.2"), TITLE("title", "urn:oid:2.5.4.12"), UID("uid",
+            "urn:oid:0.9.2342.19200300.100.1.1"), UNIQUE_IDENTIFIER("uniqueIdentifier", "urn:oid:0.9.2342.19200300.100.1.44"), UNIQUE_MEMBER(
+            "uniqueMember", "urn:oid:2.5.4.50"), USER_CERTIFICATE("userCertificate", "urn:oid:2.5.4.36"), USER_CLASS(
+            "userClass", "urn:oid:0.9.2342.19200300.100.1.8"), USER_PKCS12("userPKCS12", "urn:oid:2.16.840.1.113730.3.1.216"), USER_PASSWORD(
+            "userPassword", "urn:oid:2.5.4.35"), USER_SMIME_CERTIFICATE("userSMIMECertificate",
+            "urn:oid:2.16.840.1.113730.3.1.40"), USERID("userid", "urn:oid:0.9.2342.19200300.100.1.1"), X121_ADDRESS(
+            "x121Address", "urn:oid:2.5.4.24"), X500_UNIQUE_IDENTIFIER("x500UniqueIdentifier", "urn:oid:2.5.4.45");
+
+    private String friendlyName = null;
+    private String uri = null;
+
+    private static final Map<String, String> lookup = new HashMap<String, String>();
+
+    static {
+        for (X500SAMLProfileConstants s : EnumSet.allOf(X500SAMLProfileConstants.class))
+            lookup.put(s.friendlyName, s.uri);
+    }
+
+    private X500SAMLProfileConstants(String friendlyName, String uristr) {
+        this.uri = uristr;
+        this.friendlyName = friendlyName;
+    }
+
+    public String get() {
+        return this.uri;
+    }
+
+    public String getFriendlyName() {
+        return friendlyName;
+    }
+
+    public static String getOID(final String key) {
+        return lookup.get(key);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/factories/JBossSAMLAuthnResponseFactory.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/factories/JBossSAMLAuthnResponseFactory.java
new file mode 100755
index 0000000..ce40812
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/factories/JBossSAMLAuthnResponseFactory.java
@@ -0,0 +1,217 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.factories;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.processing.core.saml.v2.common.IDGenerator;
+import org.keycloak.saml.processing.core.saml.v2.holders.IDPInfoHolder;
+import org.keycloak.saml.processing.core.saml.v2.holders.IssuerInfoHolder;
+import org.keycloak.saml.processing.core.saml.v2.holders.SPInfoHolder;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
+import org.keycloak.dom.saml.v2.assertion.ConditionsType;
+import org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.assertion.StatementAbstractType;
+import org.keycloak.dom.saml.v2.assertion.SubjectConfirmationDataType;
+import org.keycloak.dom.saml.v2.assertion.SubjectConfirmationType;
+import org.keycloak.dom.saml.v2.assertion.SubjectType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType.RTChoiceType;
+import org.keycloak.dom.saml.v2.protocol.StatusCodeType;
+import org.keycloak.dom.saml.v2.protocol.StatusType;
+import org.w3c.dom.Element;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import java.net.URI;
+import java.util.List;
+
+/**
+ * Factory for the SAML v2 Authn Response
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 9, 2008
+ */
+public class JBossSAMLAuthnResponseFactory {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * Create a StatusType given the status code uri
+     *
+     * @param statusCodeURI
+     *
+     * @return
+     */
+    public static StatusType createStatusType(String statusCodeURI) {
+        StatusCodeType sct = new StatusCodeType();
+        sct.setValue(URI.create(statusCodeURI));
+
+        StatusType statusType = new StatusType();
+        statusType.setStatusCode(sct);
+        return statusType;
+    }
+
+    /**
+     * <p>Create a <code>StatusType</code> with a top-level <code>org.picketlink.common.constants.JBossSAMLURIConstants.STATUS_RESPONDER</code>
+     * and a second-level code reflecting the given <code>statusCodeURI</code>.</p>
+     *
+     * @param statusCodeURI The second-level code.
+     *
+     * @return
+     */
+    public static StatusType createStatusTypeForResponder(String statusCodeURI) {
+        StatusCodeType topLevelCode = new StatusCodeType();
+
+        topLevelCode.setValue(URI.create(JBossSAMLURIConstants.STATUS_RESPONDER.get()));
+
+        StatusCodeType secondLevelCode = new StatusCodeType();
+
+        secondLevelCode.setValue(URI.create(statusCodeURI));
+
+        topLevelCode.setStatusCode(secondLevelCode);
+
+        StatusType statusType = new StatusType();
+
+        statusType.setStatusCode(topLevelCode);
+
+        return statusType;
+    }
+
+    /**
+     * Create a ResponseType
+     *
+     * @param ID id of the response
+     * @param sp holder with the information about the Service Provider
+     * @param idp holder with the information on the Identity Provider
+     * @param issuerInfo holder with information on the issuer
+     *
+     * @return
+     *
+     * @throws ConfigurationException
+     */
+    public static ResponseType createResponseType(String ID, SPInfoHolder sp, IDPInfoHolder idp, IssuerInfoHolder issuerInfo)
+            throws ConfigurationException {
+        String responseDestinationURI = sp.getResponseDestinationURI();
+
+        XMLGregorianCalendar issueInstant = XMLTimeUtil.getIssueInstant();
+
+        // Create an assertion
+        String id = IDGenerator.create("ID_");
+
+        // Create assertion -> subject
+        SubjectType subjectType = new SubjectType();
+
+        // subject -> nameid
+        NameIDType nameIDType = new NameIDType();
+        nameIDType.setFormat(URI.create(idp.getNameIDFormat()));
+        nameIDType.setValue(idp.getNameIDFormatValue());
+
+        SubjectType.STSubType subType = new SubjectType.STSubType();
+        subType.addBaseID(nameIDType);
+        subjectType.setSubType(subType);
+
+        SubjectConfirmationType subjectConfirmation = new SubjectConfirmationType();
+        subjectConfirmation.setMethod(idp.getSubjectConfirmationMethod());
+
+        SubjectConfirmationDataType subjectConfirmationData = new SubjectConfirmationDataType();
+        subjectConfirmationData.setInResponseTo(sp.getRequestID());
+        subjectConfirmationData.setRecipient(responseDestinationURI);
+        //subjectConfirmationData.setNotBefore(issueInstant);
+        subjectConfirmationData.setNotOnOrAfter(issueInstant);
+
+        subjectConfirmation.setSubjectConfirmationData(subjectConfirmationData);
+
+        subjectType.addConfirmation(subjectConfirmation);
+
+        AssertionType assertionType = SAMLAssertionFactory.createAssertion(id, nameIDType, issueInstant, (ConditionsType) null,
+                subjectType, (List<StatementAbstractType>) null);
+
+        ResponseType responseType = createResponseType(ID, issuerInfo, assertionType);
+        // InResponseTo ID
+        responseType.setInResponseTo(sp.getRequestID());
+        // Destination
+        responseType.setDestination(responseDestinationURI);
+
+        return responseType;
+    }
+
+    /**
+     * Create a Response Type
+     *
+     * @param ID
+     * @param issuerInfo
+     * @param assertionType
+     *
+     * @return
+     *
+     * @throws ConfigurationException
+     */
+    public static ResponseType createResponseType(String ID, IssuerInfoHolder issuerInfo, AssertionType assertionType)
+            throws ConfigurationException {
+        XMLGregorianCalendar issueInstant = XMLTimeUtil.getIssueInstant();
+        ResponseType responseType = new ResponseType(ID, issueInstant);
+
+        // Issuer
+        NameIDType issuer = issuerInfo.getIssuer();
+        responseType.setIssuer(issuer);
+
+        // Status
+        String statusCode = issuerInfo.getStatusCode();
+        if (statusCode == null)
+            throw logger.issuerInfoMissingStatusCodeError();
+
+        responseType.setStatus(createStatusType(statusCode));
+
+        responseType.addAssertion(new RTChoiceType(assertionType));
+        return responseType;
+    }
+
+    /**
+     * Create a Response Type
+     *
+     * @param ID
+     * @param issuerInfo
+     * @param encryptedAssertion a DOM {@link Element} that represents an encrypted assertion
+     *
+     * @return
+     *
+     * @throws ConfigurationException
+     */
+    public static ResponseType createResponseType(String ID, IssuerInfoHolder issuerInfo, Element encryptedAssertion)
+            throws ConfigurationException {
+        ResponseType responseType = new ResponseType(ID, XMLTimeUtil.getIssueInstant());
+
+        // Issuer
+        NameIDType issuer = issuerInfo.getIssuer();
+        responseType.setIssuer(issuer);
+
+        // Status
+        String statusCode = issuerInfo.getStatusCode();
+        if (statusCode == null)
+            throw logger.issuerInfoMissingStatusCodeError();
+
+        responseType.setStatus(createStatusType(statusCode));
+
+        responseType.addAssertion(new RTChoiceType(new EncryptedAssertionType(encryptedAssertion)));
+        return responseType;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/factories/SAMLAssertionFactory.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/factories/SAMLAssertionFactory.java
new file mode 100755
index 0000000..3201b8a
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/factories/SAMLAssertionFactory.java
@@ -0,0 +1,197 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.factories;
+
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
+import org.keycloak.dom.saml.v2.assertion.AudienceRestrictionType;
+import org.keycloak.dom.saml.v2.assertion.ConditionAbstractType;
+import org.keycloak.dom.saml.v2.assertion.ConditionsType;
+import org.keycloak.dom.saml.v2.assertion.KeyInfoConfirmationDataType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.assertion.StatementAbstractType;
+import org.keycloak.dom.saml.v2.assertion.SubjectConfirmationType;
+import org.keycloak.dom.saml.v2.assertion.SubjectType;
+import org.keycloak.dom.xmlsec.w3.xmldsig.KeyInfoType;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import java.net.URI;
+import java.util.List;
+
+/**
+ * Deal with {@code AssertionType}
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jan 28, 2009
+ */
+public class SAMLAssertionFactory {
+
+    /**
+     * <p>
+     * Creates an {@code AudienceRestrictionType} with the specified values.
+     * </p>
+     *
+     * @param values a {@code String[]} containing the restriction values.
+     *
+     * @return the constructed {@code AudienceRestrictionType} instance.
+     */
+    public static AudienceRestrictionType createAudienceRestriction(String... values) {
+        AudienceRestrictionType audienceRestriction = new AudienceRestrictionType();
+        if (values != null) {
+            for (String val : values) {
+                audienceRestriction.addAudience(URI.create(val));
+            }
+        }
+        return audienceRestriction;
+    }
+
+    /**
+     * <p>
+     * Creates a {@code NameIDType} instance with the specified values.
+     * </p>
+     *
+     * @param format a {@code String} representing the name format.
+     * @param qualifier a {@code String} representing the name qualifier.
+     * @param value a {@code String} representing the name value.
+     *
+     * @return the constructed {@code NameIDType} instance.
+     */
+    public static NameIDType createNameID(String format, String qualifier, String value) {
+        NameIDType nameID = new NameIDType();
+        if (format != null)
+            nameID.setFormat(URI.create(format));
+        nameID.setNameQualifier(qualifier);
+        nameID.setValue(value);
+        return nameID;
+    }
+
+    /**
+     * <p>
+     * Creates a {@code Conditions} instance with the specified values.
+     * </p>
+     *
+     * @param notBefore a {@code XMLGregorianCalendar} representing the start of the token lifetime period.
+     * @param notOnOrAfter a {@code XMLGregorianCalendar} representing the end of the token lifetime period.
+     * @param restrictions an array containing the applicable restrictions.
+     *
+     * @return the constructed {@code Conditions} instance.
+     */
+    public static ConditionsType createConditions(XMLGregorianCalendar notBefore, XMLGregorianCalendar notOnOrAfter,
+                                                  ConditionAbstractType... restrictions) {
+        ConditionsType conditions = new ConditionsType();
+        conditions.setNotBefore(notBefore);
+        conditions.setNotOnOrAfter(notOnOrAfter);
+        if (restrictions != null) {
+            for (ConditionAbstractType condition : restrictions) {
+                conditions.addCondition(condition);
+            }
+
+        }
+        return conditions;
+    }
+
+    /**
+     * <p>
+     * Creates a {@code KeyInfoConfirmationDataType} with the specified {@code KeyInfoType}.
+     * </p>
+     *
+     * @param keyInfo the {@code KeyInfoType} object that wraps the proof-of-possession token.
+     *
+     * @return the constructed {@code KeyInfoConfirmationDataType} instance.
+     */
+    public static KeyInfoConfirmationDataType createKeyInfoConfirmation(KeyInfoType keyInfo) {
+        KeyInfoConfirmationDataType type = new KeyInfoConfirmationDataType();
+        type.setAnyType(keyInfo);
+        return type;
+    }
+
+    /**
+     * <p>
+     * Creates a {@code SubjectConfirmationType} object with the specified values.
+     * </p>
+     *
+     * @param nameID the identifier of the confirmation.
+     * @param confirmationMethod a {@code String} representing the confirmation method.
+     * @param keyInfoData the {@code KeyInfoConfirmationDataType} instance that contains the proof of possession key.
+     *
+     * @return the constructed {@code SubjectConfirmationType} instance.
+     */
+    public static SubjectConfirmationType createSubjectConfirmation(NameIDType nameID, String confirmationMethod,
+                                                                    KeyInfoConfirmationDataType keyInfoData) {
+        SubjectConfirmationType subjectConfirmation = new SubjectConfirmationType();
+        subjectConfirmation.setNameID(nameID);
+        subjectConfirmation.setMethod(confirmationMethod);
+        subjectConfirmation.setSubjectConfirmationData(keyInfoData);
+        return subjectConfirmation;
+    }
+
+    /**
+     * <p>
+     * Creates a {@code SubjectType} object with the specified values.
+     * </p>
+     *
+     * @param nameID the identifier of the subject.
+     * @param confirmation the {@code SubjectConfirmationType} that is used to establish the correspondence between the
+     * subject
+     * and claims of SAML statements.
+     *
+     * @return the constructed {@code SubjectType} instance.
+     */
+    public static SubjectType createSubject(NameIDType nameID, SubjectConfirmationType confirmation) {
+        SubjectType subject = new SubjectType();
+        if (nameID != null) {
+            SubjectType.STSubType subType = new SubjectType.STSubType();
+            subType.addConfirmation(confirmation);
+            subType.addBaseID(nameID);
+            subject.setSubType(subType);
+        }
+        return subject;
+    }
+
+    /**
+     * <p>
+     * Creates a SAMLV2 {@code AssertionType} with the specified values.
+     * </p>
+     *
+     * @param id a {@code String} representing the assertion ID.
+     * @param issuerID a {@code NameIDType} that identifies the assertion issuer.
+     * @param issueInstant the assertion time of creation.
+     * @param conditions the {@code ConditionsType} that specify the conditions under which the assertion is to be
+     * considered
+     * valid
+     * @param subject the {@code SubjectType} that identifies the authenticated principal.
+     * @param statements a list of statements associated with the authenticated principal.
+     *
+     * @return
+     */
+    public static AssertionType createAssertion(String id, NameIDType issuerID, XMLGregorianCalendar issueInstant,
+                                                ConditionsType conditions, SubjectType subject, List<StatementAbstractType> statements) {
+        AssertionType assertion = new AssertionType(id, issueInstant);
+        assertion.setIssuer(issuerID);
+        if (conditions != null)
+            assertion.setConditions(conditions);
+        if (subject != null)
+            assertion.setSubject(subject);
+
+        if (statements != null) {
+            for (StatementAbstractType statement : statements) {
+                assertion.addStatement(statement);
+            }
+        }
+        return assertion;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/factories/SecurityActions.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/factories/SecurityActions.java
new file mode 100755
index 0000000..5835c75
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/factories/SecurityActions.java
@@ -0,0 +1,126 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.factories;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 9, 2008
+ */
+class SecurityActions {
+
+    /**
+     * <p>
+     * Loads a {@link Class} using the <code>fullQualifiedName</code> supplied. This method tries first to load from
+     * the
+     * specified {@link Class}, if not found it will try to load from using TCL.
+     * </p>
+     *
+     * @param theClass
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final Class<?> theClass, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    ClassLoader classLoader = theClass.getClassLoader();
+
+                    Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+                    if (clazz == null) {
+                        classLoader = Thread.currentThread().getContextClassLoader();
+                        clazz = loadClass(classLoader, fullQualifiedName);
+                    }
+                    return clazz;
+                }
+            });
+        } else {
+            ClassLoader classLoader = theClass.getClassLoader();
+
+            Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+            if (clazz == null) {
+                classLoader = Thread.currentThread().getContextClassLoader();
+                clazz = loadClass(classLoader, fullQualifiedName);
+            }
+            return clazz;
+        }
+    }
+
+    /**
+     * <p>
+     * Loads a class from the specified {@link ClassLoader} using the <code>fullQualifiedName</code> supplied.
+     * </p>
+     *
+     * @param classLoader
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final ClassLoader classLoader, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    try {
+                        return classLoader.loadClass(fullQualifiedName);
+                    } catch (ClassNotFoundException e) {
+                    }
+                    return null;
+                }
+            });
+        } else {
+            try {
+                return classLoader.loadClass(fullQualifiedName);
+            } catch (ClassNotFoundException e) {
+            }
+            return null;
+        }
+    }
+
+    /**
+     * <p>Returns a system property value using the specified <code>key</code>. If not found the
+     * <code>defaultValue</code> will be returned.</p>
+     *
+     * @param key
+     * @param defaultValue
+     *
+     * @return
+     */
+    static String getSystemProperty(final String key, final String defaultValue) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty(key, defaultValue);
+                }
+            });
+        } else {
+            return System.getProperty(key, defaultValue);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/DestinationInfoHolder.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/DestinationInfoHolder.java
new file mode 100755
index 0000000..9bc56de
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/DestinationInfoHolder.java
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.holders;
+
+/**
+ * Holder containing the information about a destination
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jul 24, 2009
+ */
+public class DestinationInfoHolder {
+
+    private String destination;
+    private String samlMessage;
+    private String relayState;
+
+    /**
+     * Create an holder
+     *
+     * @param destination The destination where the post will be sent
+     * @param samlMessage SAML Message
+     * @param relayState
+     */
+    public DestinationInfoHolder(String destination, String samlMessage, String relayState) {
+        this.destination = destination;
+        this.samlMessage = samlMessage;
+        this.relayState = relayState;
+    }
+
+    public String getDestination() {
+        return destination;
+    }
+
+    public String getSamlMessage() {
+        return samlMessage;
+    }
+
+    public String getRelayState() {
+        return relayState;
+    }
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/IDPInfoHolder.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/IDPInfoHolder.java
new file mode 100755
index 0000000..89d3d1c
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/IDPInfoHolder.java
@@ -0,0 +1,78 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.holders;
+
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
+
+/**
+ * Holds essential information about an IDP for creating saml messages.
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 10, 2008
+ */
+public class IDPInfoHolder {
+
+    private String subjectConfirmationMethod = JBossSAMLURIConstants.SUBJECT_CONFIRMATION_BEARER.get();
+    private String nameIDFormat = JBossSAMLURIConstants.NAMEID_FORMAT_TRANSIENT.get();
+    private String nameIDFormatValue;
+
+    private AssertionType assertion;
+
+    private int assertionValidityDuration = 5; // 5 Minutes
+
+    public int getAssertionValidityDuration() {
+        return assertionValidityDuration;
+    }
+
+    public void setAssertionValidityDuration(int assertionValidityDuration) {
+        this.assertionValidityDuration = assertionValidityDuration;
+    }
+
+    public String getSubjectConfirmationMethod() {
+        return subjectConfirmationMethod;
+    }
+
+    public void setSubjectConfirmationMethod(String subjectConfirmationMethod) {
+        this.subjectConfirmationMethod = subjectConfirmationMethod;
+    }
+
+    public String getNameIDFormat() {
+        return nameIDFormat;
+    }
+
+    public void setNameIDFormat(String nameIDFormat) {
+        this.nameIDFormat = nameIDFormat;
+    }
+
+    public String getNameIDFormatValue() {
+        return nameIDFormatValue;
+    }
+
+    public void setNameIDFormatValue(String nameIDFormatValue) {
+        this.nameIDFormatValue = nameIDFormatValue;
+    }
+
+    public AssertionType getAssertion() {
+        return assertion;
+    }
+
+    public void setAssertion(AssertionType assertion) {
+        this.assertion = assertion;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/IssuerInfoHolder.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/IssuerInfoHolder.java
new file mode 100755
index 0000000..ccb5794
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/IssuerInfoHolder.java
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.holders;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+
+/**
+ * Holds info about the issuer for saml messages creation
+ *
+ * @param <JBossSAMLConstants>
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 10, 2008
+ */
+public class IssuerInfoHolder {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    private NameIDType issuer;
+
+    private String statusCodeURI = JBossSAMLURIConstants.STATUS_SUCCESS.get();
+
+    private String samlVersion = JBossSAMLConstants.VERSION_2_0.get();
+
+    public IssuerInfoHolder(NameIDType issuer) {
+        if (issuer == null)
+            throw logger.nullArgumentError("issuer");
+        this.issuer = issuer;
+    }
+
+    public IssuerInfoHolder(String issuerAsString) {
+        if (issuerAsString == null)
+            throw logger.nullArgumentError("issuerAsString");
+        issuer = new NameIDType();
+        issuer.setValue(issuerAsString);
+    }
+
+    public NameIDType getIssuer() {
+        return issuer;
+    }
+
+    public void setIssuer(NameIDType issuer) {
+        this.issuer = issuer;
+    }
+
+    public String getStatusCode() {
+        return statusCodeURI;
+    }
+
+    public void setStatusCode(String statusCode) {
+        this.statusCodeURI = statusCode;
+    }
+
+    public String getSamlVersion() {
+        return samlVersion;
+    }
+
+    public void setSamlVersion(String samlVersion) {
+        this.samlVersion = samlVersion;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/SignatureInfoHolder.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/SignatureInfoHolder.java
new file mode 100755
index 0000000..545d2a5
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/SignatureInfoHolder.java
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.holders;
+
+/**
+ * Holds information about signature
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jul 24, 2009
+ */
+public class SignatureInfoHolder {
+
+    private byte[] signatureValue;
+
+    private String sigAlg;
+
+    public SignatureInfoHolder(byte[] signatureValue, String sigAlg) {
+        super();
+        this.signatureValue = signatureValue;
+        this.sigAlg = sigAlg;
+    }
+
+    public byte[] getSignatureValue() {
+        return signatureValue;
+    }
+
+    public String getSigAlg() {
+        return sigAlg;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/SPInfoHolder.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/SPInfoHolder.java
new file mode 100755
index 0000000..c9ca5c3
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/holders/SPInfoHolder.java
@@ -0,0 +1,60 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.holders;
+
+/**
+ * <p>
+ * Holds the information about a Service Provider
+ * </p>
+ * <p>
+ * This holder is useful in generating saml messages
+ * </p>
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 10, 2008
+ */
+public class SPInfoHolder {
+
+    private String requestID;
+    private String responseDestinationURI;
+    private String issuer;
+
+    public String getRequestID() {
+        return requestID;
+    }
+
+    public void setRequestID(String requestID) {
+        this.requestID = requestID;
+    }
+
+    public String getResponseDestinationURI() {
+        return responseDestinationURI;
+    }
+
+    public void setResponseDestinationURI(String responseDestinationURI) {
+        this.responseDestinationURI = responseDestinationURI;
+    }
+
+    public String getIssuer() {
+        return issuer;
+    }
+
+    public void setIssuer(String issuer) {
+        this.issuer = issuer;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/DocumentUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/DocumentUtil.java
new file mode 100755
index 0000000..fa1cadc
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/DocumentUtil.java
@@ -0,0 +1,28 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.util;
+
+/**
+ * PLINK-158: Maintain backward compatibility
+ *
+ * @author Anil Saldhana
+ * @since June 20, 2013
+ */
+public class DocumentUtil extends org.keycloak.saml.common.util.DocumentUtil {
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SAMLMetadataUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SAMLMetadataUtil.java
new file mode 100755
index 0000000..bca7eb0
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SAMLMetadataUtil.java
@@ -0,0 +1,101 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.util;
+
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.processing.core.util.XMLSignatureUtil;
+import org.keycloak.dom.saml.v2.metadata.KeyDescriptorType;
+import org.keycloak.dom.saml.v2.metadata.KeyTypes;
+import org.keycloak.dom.saml.v2.metadata.SSODescriptorType;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * Deals with SAML2 Metadata
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jan 31, 2011
+ */
+public class SAMLMetadataUtil {
+
+    /**
+     * Get the {@link X509Certificate} from the KeyInfo
+     *
+     * @param keyDescriptor
+     *
+     * @return
+     *
+     * @throws org.keycloak.saml.common.exceptions.ProcessingException
+     * @throws org.keycloak.saml.common.exceptions.ConfigurationException
+     */
+    public static X509Certificate getCertificate(KeyDescriptorType keyDescriptor) throws ConfigurationException,
+            ProcessingException {
+        X509Certificate cert = null;
+        Element keyInfo = keyDescriptor.getKeyInfo();
+        if (keyInfo != null) {
+            NodeList x509DataNodes = keyInfo.getElementsByTagName("X509Data");
+            if (x509DataNodes == null || x509DataNodes.getLength() == 0) {
+                x509DataNodes = keyInfo.getElementsByTagNameNS(JBossSAMLURIConstants.XMLDSIG_NSURI.get(), "X509Data");
+            }
+
+            if (x509DataNodes == null || x509DataNodes.getLength() == 0) {
+                x509DataNodes = keyInfo.getElementsByTagName("ds:X509Data");
+            }
+
+            if (x509DataNodes != null && x509DataNodes.getLength() > 0) {
+                // Choose the first one
+                Node x509DataNode = x509DataNodes.item(0);
+                NodeList children = x509DataNode.getChildNodes();
+                int len = children != null ? children.getLength() : 0;
+                for (int i = 0; i < len; i++) {
+                    Node nl = children.item(i);
+                    if (nl.getNodeName().contains("X509Certificate")) {
+                        Node certNode = nl.getFirstChild();
+                        String certNodeValue = certNode.getNodeValue();
+                        cert = XMLSignatureUtil.getX509CertificateFromKeyInfoString(certNodeValue.replaceAll("\\s", ""));
+                        break;
+                    }
+                }
+            }
+        }
+        return cert;
+    }
+
+    public static X509Certificate getCertificate(KeyTypes use, SSODescriptorType ssoDescriptorType) {
+        if (ssoDescriptorType != null) {
+            for (KeyDescriptorType keyDescriptorType : ssoDescriptorType.getKeyDescriptor()) {
+                KeyTypes keyUse = keyDescriptorType.getUse();
+
+                if (keyUse == null || (use != null && keyUse.value().equals(use.value()))) {
+                    try {
+                        return getCertificate(keyDescriptorType);
+                    } catch (Exception e) {
+                        throw new RuntimeException("Could not parse KeyDescriptor X509 certificate from metadata [" + ssoDescriptorType.getID() + "].");
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SecurityActions.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SecurityActions.java
new file mode 100755
index 0000000..1a9c090
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SecurityActions.java
@@ -0,0 +1,161 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.util;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 9, 2008
+ */
+class SecurityActions {
+
+    /**
+     * <p>
+     * Loads a {@link Class} using the <code>fullQualifiedName</code> supplied. This method tries first to load from
+     * the
+     * specified {@link Class}, if not found it will try to load from using TCL.
+     * </p>
+     *
+     * @param theClass
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final Class<?> theClass, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    ClassLoader classLoader = theClass.getClassLoader();
+
+                    Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+                    if (clazz == null) {
+                        classLoader = Thread.currentThread().getContextClassLoader();
+                        clazz = loadClass(classLoader, fullQualifiedName);
+                    }
+                    return clazz;
+                }
+            });
+        } else {
+            ClassLoader classLoader = theClass.getClassLoader();
+
+            Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+            if (clazz == null) {
+                classLoader = Thread.currentThread().getContextClassLoader();
+                clazz = loadClass(classLoader, fullQualifiedName);
+            }
+            return clazz;
+        }
+    }
+
+    /**
+     * <p>
+     * Loads a class from the specified {@link ClassLoader} using the <code>fullQualifiedName</code> supplied.
+     * </p>
+     *
+     * @param classLoader
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final ClassLoader classLoader, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    try {
+                        return classLoader.loadClass(fullQualifiedName);
+                    } catch (ClassNotFoundException e) {
+                    }
+                    return null;
+                }
+            });
+        } else {
+            try {
+                return classLoader.loadClass(fullQualifiedName);
+            } catch (ClassNotFoundException e) {
+            }
+            return null;
+        }
+    }
+
+    /**
+     * <p>Returns a system property value using the specified <code>key</code>. If not found the
+     * <code>defaultValue</code> will be returned.</p>
+     *
+     * @param key
+     * @param defaultValue
+     *
+     * @return
+     */
+    static String getSystemProperty(final String key, final String defaultValue) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty(key, defaultValue);
+                }
+            });
+        } else {
+            return System.getProperty(key, defaultValue);
+        }
+    }
+
+    /**
+     * Get the Thread Context ClassLoader
+     *
+     * @return
+     */
+    static ClassLoader getTCCL() {
+        if (System.getSecurityManager() != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
+                    return Thread.currentThread().getContextClassLoader();
+                }
+            });
+        } else {
+            return Thread.currentThread().getContextClassLoader();
+        }
+    }
+
+    /**
+     * Set the Thread Context ClassLoader
+     *
+     * @param paramCl
+     */
+    static void setTCCL(final ClassLoader paramCl) {
+        if (System.getSecurityManager() != null) {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    Thread.currentThread().setContextClassLoader(paramCl);
+                    return null;
+                }
+            });
+        } else {
+
+            Thread.currentThread().setContextClassLoader(paramCl);
+        }
+    }
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SignatureUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SignatureUtil.java
new file mode 100755
index 0000000..1c52241
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SignatureUtil.java
@@ -0,0 +1,297 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.util;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.WSTrustConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.util.Base64;
+import org.keycloak.saml.processing.core.constants.PicketLinkFederationConstants;
+import org.keycloak.dom.xmlsec.w3.xmldsig.DSAKeyValueType;
+import org.keycloak.dom.xmlsec.w3.xmldsig.KeyValueType;
+import org.keycloak.dom.xmlsec.w3.xmldsig.RSAKeyValueType;
+import org.keycloak.dom.xmlsec.w3.xmldsig.SignatureType;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import javax.xml.bind.JAXBException;
+import java.io.OutputStream;
+import java.security.GeneralSecurityException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.RSAPublicKey;
+
+/**
+ * Signature utility for signing content
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 16, 2008
+ */
+public class SignatureUtil {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * Marshall a SignatureType to output stream
+     *
+     * @param signature
+     * @param os
+     *
+     * @throws SAXException
+     * @throws JAXBException
+     */
+    public static void marshall(SignatureType signature, OutputStream os) throws JAXBException, SAXException {
+        throw logger.notImplementedYet("NYI");
+        /*
+         * JAXBElement<SignatureType> jsig = objectFactory.createSignature(signature); Marshaller marshaller =
+         * JAXBUtil.getValidatingMarshaller(pkgName, schemaLocation); marshaller.marshal(jsig, os);
+         */
+    }
+
+    /**
+     * Get the XML Signature URI for the algo (RSA, DSA)
+     *
+     * @param algo
+     *
+     * @return
+     */
+    public static String getXMLSignatureAlgorithmURI(String algo) {
+        String xmlSignatureAlgo = null;
+
+        if ("DSA".equalsIgnoreCase(algo)) {
+            xmlSignatureAlgo = JBossSAMLConstants.SIGNATURE_SHA1_WITH_DSA.get();
+        } else if ("RSA".equalsIgnoreCase(algo)) {
+            xmlSignatureAlgo = JBossSAMLConstants.SIGNATURE_SHA1_WITH_RSA.get();
+        }
+        return xmlSignatureAlgo;
+    }
+
+    /**
+     * Sign a string using the private key
+     *
+     * @param stringToBeSigned
+     * @param signingKey
+     *
+     * @return
+     *
+     * @throws GeneralSecurityException
+     */
+    public static byte[] sign(String stringToBeSigned, PrivateKey signingKey) throws GeneralSecurityException {
+        if (stringToBeSigned == null)
+            throw logger.nullArgumentError("stringToBeSigned");
+        if (signingKey == null)
+            throw logger.nullArgumentError("signingKey");
+
+        String algo = signingKey.getAlgorithm();
+        Signature sig = getSignature(algo);
+        sig.initSign(signingKey);
+        sig.update(stringToBeSigned.getBytes());
+        return sig.sign();
+    }
+
+    /**
+     * Validate the signed content with the signature value
+     *
+     * @param signedContent
+     * @param signatureValue
+     * @param validatingKey
+     *
+     * @return
+     *
+     * @throws GeneralSecurityException
+     */
+    public static boolean validate(byte[] signedContent, byte[] signatureValue, PublicKey validatingKey)
+            throws GeneralSecurityException {
+        if (signedContent == null)
+            throw logger.nullArgumentError("signedContent");
+        if (signatureValue == null)
+            throw logger.nullArgumentError("signatureValue");
+        if (validatingKey == null)
+            throw logger.nullArgumentError("validatingKey");
+
+        // We assume that the sigatureValue has the same algorithm as the public key
+        // If not, there will be an exception anyway
+        String algo = validatingKey.getAlgorithm();
+        Signature sig = getSignature(algo);
+
+        sig.initVerify(validatingKey);
+        sig.update(signedContent);
+        return sig.verify(signatureValue);
+    }
+
+    /**
+     * Validate the signature using a x509 certificate
+     *
+     * @param signedContent
+     * @param signatureValue
+     * @param signatureAlgorithm
+     * @param validatingCert
+     *
+     * @return
+     *
+     * @throws GeneralSecurityException
+     */
+    public static boolean validate(byte[] signedContent, byte[] signatureValue, String signatureAlgorithm,
+                                   X509Certificate validatingCert) throws GeneralSecurityException {
+        if (signedContent == null)
+            throw logger.nullArgumentError("signedContent");
+        if (signatureValue == null)
+            throw logger.nullArgumentError("signatureValue");
+        if (signatureAlgorithm == null)
+            throw logger.nullArgumentError("signatureAlgorithm");
+        if (validatingCert == null)
+            throw logger.nullArgumentError("validatingCert");
+
+        Signature sig = getSignature(signatureAlgorithm);
+
+        sig.initVerify(validatingCert);
+        sig.update(signedContent);
+        return sig.verify(signatureValue);
+    }
+
+
+    /**
+     * Given a dsig:DSAKeyValue element, return {@link DSAKeyValueType}
+     *
+     * @param element
+     *
+     * @return
+     *
+     * @throws org.keycloak.saml.common.exceptions.ParsingException
+     */
+    public static DSAKeyValueType getDSAKeyValue(Element element) throws ParsingException {
+        DSAKeyValueType dsa = new DSAKeyValueType();
+        NodeList nl = element.getChildNodes();
+        int length = nl.getLength();
+
+        for (int i = 0; i < length; i++) {
+            Node node = nl.item(i);
+            if (node instanceof Element) {
+                Element childElement = (Element) node;
+                String tag = childElement.getLocalName();
+
+                byte[] text = childElement.getTextContent().getBytes();
+
+                if (WSTrustConstants.XMLDSig.P.equals(tag)) {
+                    dsa.setP(text);
+                } else if (WSTrustConstants.XMLDSig.Q.equals(tag)) {
+                    dsa.setQ(text);
+                } else if (WSTrustConstants.XMLDSig.G.equals(tag)) {
+                    dsa.setG(text);
+                } else if (WSTrustConstants.XMLDSig.Y.equals(tag)) {
+                    dsa.setY(text);
+                } else if (WSTrustConstants.XMLDSig.SEED.equals(tag)) {
+                    dsa.setSeed(text);
+                } else if (WSTrustConstants.XMLDSig.PGEN_COUNTER.equals(tag)) {
+                    dsa.setPgenCounter(text);
+                }
+            }
+        }
+
+        return dsa;
+    }
+
+    /**
+     * Given a dsig:DSAKeyValue element, return {@link DSAKeyValueType}
+     *
+     * @param element
+     *
+     * @return
+     *
+     * @throws ParsingException
+     */
+    public static RSAKeyValueType getRSAKeyValue(Element element) throws ParsingException {
+        RSAKeyValueType rsa = new RSAKeyValueType();
+        NodeList nl = element.getChildNodes();
+        int length = nl.getLength();
+
+        for (int i = 0; i < length; i++) {
+            Node node = nl.item(i);
+            if (node instanceof Element) {
+                Element childElement = (Element) node;
+                String tag = childElement.getLocalName();
+
+                byte[] text = childElement.getTextContent().getBytes();
+
+                if (WSTrustConstants.XMLDSig.MODULUS.equals(tag)) {
+                    rsa.setModulus(text);
+                } else if (WSTrustConstants.XMLDSig.EXPONENT.equals(tag)) {
+                    rsa.setExponent(text);
+                }
+            }
+        }
+
+        return rsa;
+    }
+
+    /**
+     * <p>
+     * Creates a {@code KeyValueType} that wraps the specified public key. This method supports DSA and RSA keys.
+     * </p>
+     *
+     * @param key the {@code PublicKey} that will be represented as a {@code KeyValueType}.
+     *
+     * @return the constructed {@code KeyValueType} or {@code null} if the specified key is neither a DSA nor a RSA
+     *         key.
+     */
+    public static KeyValueType createKeyValue(PublicKey key) {
+        if (key instanceof RSAPublicKey) {
+            RSAPublicKey pubKey = (RSAPublicKey) key;
+            byte[] modulus = pubKey.getModulus().toByteArray();
+            byte[] exponent = pubKey.getPublicExponent().toByteArray();
+
+            RSAKeyValueType rsaKeyValue = new RSAKeyValueType();
+            rsaKeyValue.setModulus(Base64.encodeBytes(modulus).getBytes());
+            rsaKeyValue.setExponent(Base64.encodeBytes(exponent).getBytes());
+            return rsaKeyValue;
+        } else if (key instanceof DSAPublicKey) {
+            DSAPublicKey pubKey = (DSAPublicKey) key;
+            byte[] P = pubKey.getParams().getP().toByteArray();
+            byte[] Q = pubKey.getParams().getQ().toByteArray();
+            byte[] G = pubKey.getParams().getG().toByteArray();
+            byte[] Y = pubKey.getY().toByteArray();
+
+            DSAKeyValueType dsaKeyValue = new DSAKeyValueType();
+            dsaKeyValue.setP(Base64.encodeBytes(P).getBytes());
+            dsaKeyValue.setQ(Base64.encodeBytes(Q).getBytes());
+            dsaKeyValue.setG(Base64.encodeBytes(G).getBytes());
+            dsaKeyValue.setY(Base64.encodeBytes(Y).getBytes());
+            return dsaKeyValue;
+        }
+        throw logger.unsupportedType(key.toString());
+    }
+
+    private static Signature getSignature(String algo) throws GeneralSecurityException {
+        Signature sig = null;
+
+        if ("DSA".equalsIgnoreCase(algo)) {
+            sig = Signature.getInstance(PicketLinkFederationConstants.DSA_SIGNATURE_ALGORITHM);
+        } else if ("RSA".equalsIgnoreCase(algo)) {
+            sig = Signature.getInstance(PicketLinkFederationConstants.RSA_SIGNATURE_ALGORITHM);
+        } else
+            throw logger.signatureUnknownAlgo(algo);
+        return sig;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/StatementUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/StatementUtil.java
new file mode 100755
index 0000000..c184e58
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/StatementUtil.java
@@ -0,0 +1,241 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.keycloak.saml.processing.core.saml.v2.util;
+
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.util.StringUtil;
+import org.keycloak.saml.processing.core.constants.AttributeConstants;
+import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants;
+import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
+import org.keycloak.dom.saml.v2.assertion.AttributeStatementType.ASTChoiceType;
+import org.keycloak.dom.saml.v2.assertion.AttributeType;
+import org.keycloak.dom.saml.v2.assertion.AuthnContextClassRefType;
+import org.keycloak.dom.saml.v2.assertion.AuthnContextType;
+import org.keycloak.dom.saml.v2.assertion.AuthnStatementType;
+import org.keycloak.dom.saml.v2.assertion.StatementAbstractType;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Deals with SAML2 Statements
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Aug 31, 2009
+ */
+public class StatementUtil {
+
+    public static final QName X500_QNAME = new QName(JBossSAMLURIConstants.X500_NSURI.get(), "Encoding",
+            JBossSAMLURIConstants.X500_PREFIX.get());
+
+    /**
+     * Create an AuthnStatementType given the issue instant and the type of authentication
+     *
+     * @param instant an instanceof {@link XMLGregorianCalendar}
+     * @param authnContextClassRefValue indicate the type of authentication performed
+     *
+     * @return {@link AuthnStatementType}
+     */
+    public static AuthnStatementType createAuthnStatement(XMLGregorianCalendar instant, String authnContextClassRefValue) {
+        AuthnStatementType authnStatement = new AuthnStatementType(instant);
+
+        AuthnContextType authnContext = new AuthnContextType();
+        AuthnContextClassRefType authnContextClassRef = new AuthnContextClassRefType(URI.create(authnContextClassRefValue));
+
+        AuthnContextType.AuthnContextTypeSequence sequence = (authnContext).new AuthnContextTypeSequence();
+        sequence.setClassRef(authnContextClassRef);
+        authnContext.setSequence(sequence);
+
+        authnStatement.setAuthnContext(authnContext);
+
+        return authnStatement;
+    }
+
+    /**
+     * Create an attribute statement with all the attributes
+     *
+     * @param attributes a map with keys from {@link AttributeConstants}
+     *
+     * @return
+     */
+    public static AttributeStatementType createAttributeStatement(Map<String, Object> attributes) {
+        AttributeStatementType attrStatement = null;
+
+        int i = 0;
+
+        Set<String> keys = attributes.keySet();
+        for (String key : keys) {
+            if (i == 0) {
+                // Deal with the X500 Profile of SAML2
+                attrStatement = new AttributeStatementType();
+                i++;
+            }
+
+            // if the attribute contains roles, add each role as an attribute.
+            if (AttributeConstants.ROLES.equalsIgnoreCase(key)) {
+                Object value = attributes.get(key);
+                if (value instanceof Collection<?>) {
+                    Collection<?> roles = (Collection<?>) value;
+                    attrStatement = createAttributeStatement(new ArrayList(roles));
+                }
+            } else {
+                AttributeType att;
+                Object value = attributes.get(key);
+
+                String uri = X500SAMLProfileConstants.getOID(key);
+                if (StringUtil.isNotNull(uri)) {
+                    att = getX500Attribute(uri);
+                    att.setFriendlyName(key);
+                } else {
+                    att = new AttributeType(key);
+                    att.setFriendlyName(key);
+                    att.setNameFormat(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_URI.get());
+                }
+
+                if (Collection.class.isInstance(value)) {
+                    Collection collection = (Collection) value;
+                    Iterator iterator = collection.iterator();
+
+                    while (iterator.hasNext()) {
+                        att.addAttributeValue(iterator.next());
+                    }
+                } else if (String.class.isInstance(value)) {
+                    att.addAttributeValue(value);
+                } else {
+                    throw new RuntimeException("Unsupported attribute value [" + value + "]. Values must be a string, even if using a Collection.");
+                }
+
+                attrStatement.addAttribute(new ASTChoiceType(att));
+            }
+        }
+        return attrStatement;
+    }
+
+    /**
+     * Given a set of roles, create an attribute statement
+     *
+     * @param roles
+     *
+     * @return
+     */
+    public static AttributeStatementType createAttributeStatement(List<String> roles) {
+        AttributeStatementType attrStatement = null;
+        for (String role : roles) {
+            if (attrStatement == null) {
+                attrStatement = new AttributeStatementType();
+            }
+            AttributeType attr = new AttributeType(AttributeConstants.ROLE_IDENTIFIER_ASSERTION);
+            attr.addAttributeValue(role);
+            attrStatement.addAttribute(new ASTChoiceType(attr));
+        }
+        return attrStatement;
+    }
+
+    /**
+     * Given a set of roles, create an attribute statement
+     *
+     * @param roles
+     * @param multivalued if you want the attribute to be multi valued
+     *
+     * @return
+     */
+    public static AttributeStatementType createAttributeStatementForRoles(List<String> roles, boolean multivalued) {
+        if (multivalued == false) {
+            return createAttributeStatement(roles);
+        }
+        AttributeStatementType attrStatement = new AttributeStatementType();
+        AttributeType attr = new AttributeType(AttributeConstants.ROLE_IDENTIFIER_ASSERTION);
+        for (String role : roles) {
+            attr.addAttributeValue(role);
+        }
+        attrStatement.addAttribute(new ASTChoiceType(attr));
+        return attrStatement;
+    }
+
+    /**
+     * Given an attribute type and a value, create {@link AttributeStatementType}
+     *
+     * @param key attribute type
+     * @param value attribute value
+     *
+     * @return
+     */
+    public static AttributeStatementType createAttributeStatement(String key, String value) {
+        AttributeStatementType attrStatement = new AttributeStatementType();
+        AttributeType attr = new AttributeType(key);
+        attr.addAttributeValue(value);
+        attrStatement.addAttribute(new ASTChoiceType(attr));
+
+        return attrStatement;
+    }
+
+    public static Map<String, Object> asMap(Set<AttributeStatementType> attributeStatementTypes) {
+        Map<String, Object> attrMap = new HashMap<String, Object>();
+
+        if (attributeStatementTypes != null && !attributeStatementTypes.isEmpty()) {
+            attrMap = new HashMap<String, Object>();
+
+            for (StatementAbstractType statement : attributeStatementTypes) {
+                if (statement instanceof AttributeStatementType) {
+                    AttributeStatementType attrStat = (AttributeStatementType) statement;
+                    List<ASTChoiceType> attrs = attrStat.getAttributes();
+                    for (ASTChoiceType attrChoice : attrs) {
+                        AttributeType attr = attrChoice.getAttribute();
+                        String attributeName = attr.getFriendlyName();
+
+                        if (attributeName == null) {
+                            attributeName = attr.getName();
+                        }
+
+                        List<Object> values = attr.getAttributeValue();
+
+                        if (values != null) {
+                            if (values.size() == 1) {
+                                attrMap.put(attributeName, values.get(0));
+                            } else {
+                                attrMap.put(attributeName, values);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return attrMap;
+    }
+
+    private static AttributeType getX500Attribute(String name) {
+        AttributeType att = new AttributeType(name);
+        att.getOtherAttributes().put(X500_QNAME, "LDAP");
+
+        att.setNameFormat(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_URI.get());
+        return att;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/StaxWriterUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/StaxWriterUtil.java
new file mode 100755
index 0000000..9da4caf
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/StaxWriterUtil.java
@@ -0,0 +1,166 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.util;
+
+
+import org.keycloak.saml.common.ErrorCodes;
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.WSTrustConstants;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.util.StaxUtil;
+import org.keycloak.dom.xmlsec.w3.xmldsig.DSAKeyValueType;
+import org.keycloak.dom.xmlsec.w3.xmldsig.KeyInfoType;
+import org.keycloak.dom.xmlsec.w3.xmldsig.KeyValueType;
+import org.keycloak.dom.xmlsec.w3.xmldsig.RSAKeyValueType;
+import org.keycloak.dom.xmlsec.w3.xmldsig.X509CertificateType;
+import org.keycloak.dom.xmlsec.w3.xmldsig.X509DataType;
+import org.w3c.dom.Element;
+
+import javax.xml.stream.XMLStreamWriter;
+
+/**
+ * Utility methods for stax writing
+ *
+ * @author anil saldhana
+ * @since Jan 28, 2013
+ */
+public class StaxWriterUtil {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * Write the {@link org.keycloak.dom.xmlsec.w3.xmldsig.KeyInfoType}
+     *
+     * @param writer
+     * @param keyInfo
+     *
+     * @throws org.keycloak.saml.common.exceptions.ProcessingException
+     */
+    public static void writeKeyInfo(XMLStreamWriter writer, KeyInfoType keyInfo) throws ProcessingException {
+        if (keyInfo.getContent() == null || keyInfo.getContent().size() == 0)
+            throw logger.writerInvalidKeyInfoNullContentError();
+        StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.KEYINFO,
+                WSTrustConstants.XMLDSig.DSIG_NS);
+        StaxUtil.writeNameSpace(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.DSIG_NS);
+        // write the keyInfo content.
+        Object content = keyInfo.getContent().get(0);
+        if (content instanceof Element) {
+            Element element = (Element) keyInfo.getContent().get(0);
+            StaxUtil.writeDOMNode(writer, element);
+        } else if (content instanceof X509DataType) {
+            X509DataType type = (X509DataType) content;
+            if (type.getDataObjects().size() == 0)
+                throw logger.writerNullValueError("X509Data");
+            StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.X509DATA,
+                    WSTrustConstants.XMLDSig.DSIG_NS);
+            Object obj = type.getDataObjects().get(0);
+            if (obj instanceof Element) {
+                Element element = (Element) obj;
+                StaxUtil.writeDOMElement(writer, element);
+            } else if (obj instanceof X509CertificateType) {
+                X509CertificateType cert = (X509CertificateType) obj;
+                StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.X509CERT,
+                        WSTrustConstants.XMLDSig.DSIG_NS);
+                StaxUtil.writeCharacters(writer, new String(cert.getEncodedCertificate()));
+                StaxUtil.writeEndElement(writer);
+            }
+            StaxUtil.writeEndElement(writer);
+        } else if (content instanceof KeyValueType) {
+            KeyValueType keyvalueType = (KeyValueType) content;
+            StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.KEYVALUE,
+                    WSTrustConstants.XMLDSig.DSIG_NS);
+            if (keyvalueType instanceof DSAKeyValueType) {
+                writeDSAKeyValueType(writer, (DSAKeyValueType) keyvalueType);
+            }
+            if (keyvalueType instanceof RSAKeyValueType) {
+                writeRSAKeyValueType(writer, (RSAKeyValueType) keyvalueType);
+            }
+            StaxUtil.writeEndElement(writer);
+        } else
+            throw new ProcessingException(ErrorCodes.UNSUPPORTED_TYPE + content);
+
+        StaxUtil.writeEndElement(writer);
+    }
+
+    public static void writeRSAKeyValueType(XMLStreamWriter writer, RSAKeyValueType type) throws ProcessingException {
+        String prefix = WSTrustConstants.XMLDSig.DSIG_PREFIX;
+
+        StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.RSA_KEYVALUE, WSTrustConstants.DSIG_NS);
+        // write the rsa key modulus.
+        byte[] modulus = type.getModulus();
+        StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.MODULUS, WSTrustConstants.DSIG_NS);
+        StaxUtil.writeCharacters(writer, new String(modulus));
+        StaxUtil.writeEndElement(writer);
+
+        // write the rsa key exponent.
+        byte[] exponent = type.getExponent();
+        StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.EXPONENT, WSTrustConstants.DSIG_NS);
+        StaxUtil.writeCharacters(writer, new String(exponent));
+        StaxUtil.writeEndElement(writer);
+
+        StaxUtil.writeEndElement(writer);
+    }
+
+    public static void writeDSAKeyValueType(XMLStreamWriter writer, DSAKeyValueType type) throws ProcessingException {
+
+        String prefix = WSTrustConstants.XMLDSig.DSIG_PREFIX;
+
+        StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.DSA_KEYVALUE, WSTrustConstants.DSIG_NS);
+
+        byte[] p = type.getP();
+        if (p != null) {
+            StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.P, WSTrustConstants.DSIG_NS);
+            StaxUtil.writeCharacters(writer, new String(p));
+            StaxUtil.writeEndElement(writer);
+        }
+        byte[] q = type.getQ();
+        if (q != null) {
+            StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.Q, WSTrustConstants.DSIG_NS);
+            StaxUtil.writeCharacters(writer, new String(q));
+            StaxUtil.writeEndElement(writer);
+        }
+        byte[] g = type.getG();
+        if (g != null) {
+            StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.G, WSTrustConstants.DSIG_NS);
+            StaxUtil.writeCharacters(writer, new String(g));
+            StaxUtil.writeEndElement(writer);
+        }
+        byte[] y = type.getY();
+        if (y != null) {
+            StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.Y, WSTrustConstants.DSIG_NS);
+            StaxUtil.writeCharacters(writer, new String(y));
+            StaxUtil.writeEndElement(writer);
+        }
+        byte[] seed = type.getSeed();
+        if (seed != null) {
+            StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.SEED, WSTrustConstants.DSIG_NS);
+            StaxUtil.writeCharacters(writer, new String(seed));
+            StaxUtil.writeEndElement(writer);
+        }
+        byte[] pgen = type.getPgenCounter();
+        if (pgen != null) {
+            StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.PGEN_COUNTER, WSTrustConstants.DSIG_NS);
+            StaxUtil.writeCharacters(writer, new String(pgen));
+            StaxUtil.writeEndElement(writer);
+        }
+
+        StaxUtil.writeEndElement(writer);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/XMLTimeUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/XMLTimeUtil.java
new file mode 100755
index 0000000..acb6ceb
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/XMLTimeUtil.java
@@ -0,0 +1,254 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.util;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.util.SystemPropertiesUtil;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeConstants;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.Duration;
+import javax.xml.datatype.XMLGregorianCalendar;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+/**
+ * Util class dealing with xml based time
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jan 6, 2009
+ */
+public class XMLTimeUtil {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * Add additional time in miliseconds
+     *
+     * @param value calendar whose value needs to be updated
+     * @param milis
+     *
+     * @return calendar value with the addition
+     *
+     * @throws org.keycloak.saml.common.exceptions.ConfigurationException
+     */
+    public static XMLGregorianCalendar add(XMLGregorianCalendar value, long milis) throws ConfigurationException {
+        XMLGregorianCalendar newVal = (XMLGregorianCalendar) value.clone();
+
+        Duration duration;
+        try {
+            duration = newDatatypeFactory().newDuration(milis);
+        } catch (DatatypeConfigurationException e) {
+            throw logger.configurationError(e);
+        }
+        newVal.add(duration);
+        return newVal;
+    }
+
+    /**
+     * Subtract some miliseconds from the time value
+     *
+     * @param value
+     * @param milis miliseconds entered in a positive value
+     *
+     * @return
+     *
+     * @throws ConfigurationException
+     */
+    public static XMLGregorianCalendar subtract(XMLGregorianCalendar value, long milis) throws ConfigurationException {
+        if (milis < 0)
+            throw logger.invalidArgumentError("milis should be a positive value");
+        return add(value, -1 * milis);
+    }
+
+    /**
+     * Returns a XMLGregorianCalendar in the timezone specified. If the timezone is not valid, then the timezone falls
+     * back to
+     * "GMT"
+     *
+     * @param timezone
+     *
+     * @return
+     *
+     * @throws ConfigurationException
+     */
+    public static XMLGregorianCalendar getIssueInstant(String timezone) throws ConfigurationException {
+        TimeZone tz = TimeZone.getTimeZone(timezone);
+        DatatypeFactory dtf;
+        try {
+            dtf = newDatatypeFactory();
+        } catch (DatatypeConfigurationException e) {
+            throw logger.configurationError(e);
+        }
+
+        GregorianCalendar gc = new GregorianCalendar(tz);
+        XMLGregorianCalendar xgc = dtf.newXMLGregorianCalendar(gc);
+
+        return xgc;
+    }
+
+    /**
+     * Get the current instant of time
+     *
+     * @return
+     *
+     * @throws ConfigurationException
+     */
+    public static XMLGregorianCalendar getIssueInstant() throws ConfigurationException {
+        return getIssueInstant(getCurrentTimeZoneID());
+    }
+
+    public static String getCurrentTimeZoneID() {
+        String timezonePropertyValue = SecurityActions.getSystemProperty(GeneralConstants.TIMEZONE, "GMT");
+
+        TimeZone timezone;
+        if (GeneralConstants.TIMEZONE_DEFAULT.equals(timezonePropertyValue)) {
+            timezone = TimeZone.getDefault();
+        } else {
+            timezone = TimeZone.getTimeZone(timezonePropertyValue);
+        }
+
+        return timezone.getID();
+    }
+
+    /**
+     * Convert the minutes into miliseconds
+     *
+     * @param valueInMins
+     *
+     * @return
+     */
+    public static long inMilis(int valueInMins) {
+        return valueInMins * 60 * 1000;
+    }
+
+    /**
+     * Validate that the current time falls between the two boundaries
+     *
+     * @param now
+     * @param notbefore
+     * @param notOnOrAfter
+     *
+     * @return
+     */
+    public static boolean isValid(XMLGregorianCalendar now, XMLGregorianCalendar notbefore, XMLGregorianCalendar notOnOrAfter) {
+        int val = 0;
+
+        if (notbefore != null) {
+            val = notbefore.compare(now);
+
+            if (val == DatatypeConstants.INDETERMINATE || val == DatatypeConstants.GREATER)
+                return false;
+        }
+
+        if (notOnOrAfter != null) {
+            val = notOnOrAfter.compare(now);
+
+            if (val != DatatypeConstants.GREATER)
+                return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Given a string, get the Duration object. The string can be an ISO 8601 period representation (Eg.: P10M) or a
+     * numeric
+     * value. If a ISO 8601 period, the duration will reflect the defined format. If a numeric (Eg.: 1000) the duration
+     * will
+     * be calculated in milliseconds.
+     *
+     * @param timeValue
+     *
+     * @return
+     *
+     * @throws org.keycloak.saml.common.exceptions.ParsingException
+     */
+    public static Duration parseAsDuration(String timeValue) throws ParsingException {
+        if (timeValue == null) {
+            PicketLinkLoggerFactory.getLogger().nullArgumentError("duration time");
+        }
+
+        DatatypeFactory factory = null;
+
+        try {
+            factory = newDatatypeFactory();
+        } catch (DatatypeConfigurationException e) {
+            throw logger.parserError(e);
+        }
+
+        try {
+            // checks if it is a ISO 8601 period. If not it must be a numeric value.
+            if (timeValue.startsWith("P")) {
+                return factory.newDuration(timeValue);
+            } else {
+                return factory.newDuration(Long.valueOf(timeValue));
+            }
+        } catch (Exception e) {
+            throw logger.samlMetaDataFailedToCreateCacheDuration(timeValue);
+        }
+    }
+
+    /**
+     * Given a string representing xml time, parse into {@code XMLGregorianCalendar}
+     *
+     * @param timeString
+     *
+     * @return
+     *
+     * @throws ParsingException
+     */
+    public static XMLGregorianCalendar parse(String timeString) throws ParsingException {
+        DatatypeFactory factory = null;
+        try {
+            factory = newDatatypeFactory();
+        } catch (DatatypeConfigurationException e) {
+            throw logger.parserError(e);
+        }
+        return factory.newXMLGregorianCalendar(timeString);
+    }
+
+
+    /**
+     * Create a new {@link DatatypeFactory}
+     *
+     * @return
+     *
+     * @throws DatatypeConfigurationException
+     */
+    public static DatatypeFactory newDatatypeFactory() throws DatatypeConfigurationException {
+        boolean tccl_jaxp = SystemPropertiesUtil.getSystemProperty(GeneralConstants.TCCL_JAXP, "false")
+                .equalsIgnoreCase("true");
+        ClassLoader prevTCCL = SecurityActions.getTCCL();
+        try {
+            if (tccl_jaxp) {
+                SecurityActions.setTCCL(XMLTimeUtil.class.getClassLoader());
+            }
+            return DatatypeFactory.newInstance();
+        } finally {
+            if (tccl_jaxp) {
+                SecurityActions.setTCCL(prevTCCL);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/BaseWriter.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/BaseWriter.java
new file mode 100755
index 0000000..a484a19
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/BaseWriter.java
@@ -0,0 +1,322 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.writers;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.util.StaxUtil;
+import org.keycloak.saml.common.util.StringUtil;
+import org.keycloak.saml.processing.core.saml.v2.util.StaxWriterUtil;
+import org.keycloak.dom.saml.v2.assertion.AttributeType;
+import org.keycloak.dom.saml.v2.assertion.BaseIDAbstractType;
+import org.keycloak.dom.saml.v2.assertion.EncryptedElementType;
+import org.keycloak.dom.saml.v2.assertion.KeyInfoConfirmationDataType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.assertion.SubjectConfirmationDataType;
+import org.keycloak.dom.saml.v2.assertion.SubjectConfirmationType;
+import org.keycloak.dom.saml.v2.assertion.SubjectType;
+import org.keycloak.dom.saml.v2.metadata.LocalizedNameType;
+import org.keycloak.dom.xmlsec.w3.xmldsig.KeyInfoType;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamWriter;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import static org.keycloak.saml.common.constants.JBossSAMLURIConstants.ASSERTION_NSURI;
+
+/**
+ * Base Class for the Stax writers for SAML
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Nov 2, 2010
+ */
+public class BaseWriter {
+
+    protected static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    protected static String PROTOCOL_PREFIX = "samlp";
+
+    protected static String ASSERTION_PREFIX = "saml";
+
+    protected static String XACML_SAML_PREFIX = "xacml-saml";
+
+    protected static String XACML_SAML_PROTO_PREFIX = "xacml-samlp";
+
+    protected static String XSI_PREFIX = "xsi";
+
+    protected XMLStreamWriter writer = null;
+
+    public BaseWriter(XMLStreamWriter writer) {
+        this.writer = writer;
+    }
+
+    /**
+     * Write {@code NameIDType} to stream
+     *
+     * @param nameIDType
+     * @param tag
+     * @param out
+     *
+     * @throws org.keycloak.saml.common.exceptions.ProcessingException
+     */
+    public void write(NameIDType nameIDType, QName tag) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, tag.getPrefix(), tag.getLocalPart(), tag.getNamespaceURI());
+
+        StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, ASSERTION_NSURI.get());
+
+        URI format = nameIDType.getFormat();
+        if (format != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.FORMAT.get(), format.toASCIIString());
+        }
+
+        String spProvidedID = nameIDType.getSPProvidedID();
+        if (StringUtil.isNotNull(spProvidedID)) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.SP_PROVIDED_ID.get(), spProvidedID);
+        }
+
+        String spNameQualifier = nameIDType.getSPNameQualifier();
+        if (StringUtil.isNotNull(spNameQualifier)) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.SP_NAME_QUALIFIER.get(), spNameQualifier);
+        }
+
+        String nameQualifier = nameIDType.getNameQualifier();
+        if (StringUtil.isNotNull(nameQualifier)) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.NAME_QUALIFIER.get(), nameQualifier);
+        }
+
+        String value = nameIDType.getValue();
+        if (StringUtil.isNotNull(value)) {
+            StaxUtil.writeCharacters(writer, value);
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    /**
+     * Write an {@code AttributeType} to stream
+     *
+     * @param attributeType
+     * @param out
+     *
+     * @throws ProcessingException
+     */
+    public void write(AttributeType attributeType) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.ATTRIBUTE.get(), ASSERTION_NSURI.get());
+
+        writeAttributeTypeWithoutRootTag(attributeType);
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    public void writeAttributeTypeWithoutRootTag(AttributeType attributeType) throws ProcessingException {
+        String attributeName = attributeType.getName();
+        if (attributeName != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.NAME.get(), attributeName);
+        }
+
+        String friendlyName = attributeType.getFriendlyName();
+        if (StringUtil.isNotNull(friendlyName)) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.FRIENDLY_NAME.get(), friendlyName);
+        }
+
+        String nameFormat = attributeType.getNameFormat();
+        if (StringUtil.isNotNull(nameFormat)) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.NAME_FORMAT.get(), nameFormat);
+        }
+
+        // Take care of other attributes such as x500:encoding
+        Map<QName, String> otherAttribs = attributeType.getOtherAttributes();
+        if (otherAttribs != null) {
+            List<String> nameSpacesDealt = new ArrayList<String>();
+
+            Iterator<QName> keySet = otherAttribs.keySet().iterator();
+            while (keySet != null && keySet.hasNext()) {
+                QName qname = keySet.next();
+                String ns = qname.getNamespaceURI();
+                if (!nameSpacesDealt.contains(ns)) {
+                    StaxUtil.writeNameSpace(writer, qname.getPrefix(), ns);
+                    nameSpacesDealt.add(ns);
+                }
+                String attribValue = otherAttribs.get(qname);
+                StaxUtil.writeAttribute(writer, qname, attribValue);
+            }
+        }
+
+        List<Object> attributeValues = attributeType.getAttributeValue();
+        if (attributeValues != null) {
+            for (Object attributeValue : attributeValues) {
+                if (attributeValue != null) {
+                    if (attributeValue instanceof String) {
+                        writeStringAttributeValue((String) attributeValue);
+                    } else
+                        throw logger.writerUnsupportedAttributeValueError(attributeValue.getClass().getName());
+                }
+            }
+        }
+    }
+
+    public void writeStringAttributeValue(String attributeValue) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.ATTRIBUTE_VALUE.get(), ASSERTION_NSURI.get());
+
+        StaxUtil.writeNameSpace(writer, JBossSAMLURIConstants.XSI_PREFIX.get(), JBossSAMLURIConstants.XSI_NSURI.get());
+        StaxUtil.writeNameSpace(writer, "xs", JBossSAMLURIConstants.XMLSCHEMA_NSURI.get());
+        StaxUtil.writeAttribute(writer, "xsi", JBossSAMLURIConstants.XSI_NSURI.get(), "type", "xs:string");
+        StaxUtil.writeCharacters(writer, attributeValue);
+        StaxUtil.writeEndElement(writer);
+    }
+
+    public void writeLocalizedNameType(LocalizedNameType localizedNameType, QName startElement) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, startElement.getPrefix(), startElement.getLocalPart(),
+                startElement.getNamespaceURI());
+        StaxUtil.writeAttribute(writer, new QName(JBossSAMLURIConstants.XML.get(), "lang", "xml"), localizedNameType.getLang());
+        StaxUtil.writeCharacters(writer, localizedNameType.getValue());
+        StaxUtil.writeEndElement(writer);
+    }
+
+    /**
+     * write an {@code SubjectType} to stream
+     *
+     * @param subject
+     * @param out
+     *
+     * @throws ProcessingException
+     */
+    public void write(SubjectType subject) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.SUBJECT.get(), ASSERTION_NSURI.get());
+
+        SubjectType.STSubType subType = subject.getSubType();
+        if (subType != null) {
+            BaseIDAbstractType baseID = subType.getBaseID();
+            if (baseID instanceof NameIDType) {
+                NameIDType nameIDType = (NameIDType) baseID;
+                write(nameIDType, new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.NAMEID.get(), ASSERTION_PREFIX));
+            }
+            EncryptedElementType enc = subType.getEncryptedID();
+            if (enc != null)
+                throw new RuntimeException("NYI");
+            List<SubjectConfirmationType> confirmations = subType.getConfirmation();
+            if (confirmations != null) {
+                for (SubjectConfirmationType confirmation : confirmations) {
+                    write(confirmation);
+                }
+            }
+        }
+        List<SubjectConfirmationType> subjectConfirmations = subject.getConfirmation();
+        if (subjectConfirmations != null) {
+            for (SubjectConfirmationType subjectConfirmationType : subjectConfirmations) {
+                write(subjectConfirmationType);
+            }
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    private void write(SubjectConfirmationType subjectConfirmationType) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.SUBJECT_CONFIRMATION.get(),
+                ASSERTION_NSURI.get());
+
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.METHOD.get(), subjectConfirmationType.getMethod());
+
+        BaseIDAbstractType baseID = subjectConfirmationType.getBaseID();
+        if (baseID != null) {
+            write(baseID);
+        }
+        NameIDType nameIDType = subjectConfirmationType.getNameID();
+        if (nameIDType != null) {
+            write(nameIDType, new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.NAMEID.get(), ASSERTION_PREFIX));
+        }
+        SubjectConfirmationDataType subjectConfirmationData = subjectConfirmationType.getSubjectConfirmationData();
+        if (subjectConfirmationData != null) {
+            write(subjectConfirmationData);
+        }
+        StaxUtil.writeEndElement(writer);
+    }
+
+    private void write(SubjectConfirmationDataType subjectConfirmationData) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.SUBJECT_CONFIRMATION_DATA.get(),
+                ASSERTION_NSURI.get());
+
+        // Let us look at attributes
+        String inResponseTo = subjectConfirmationData.getInResponseTo();
+        if (StringUtil.isNotNull(inResponseTo)) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.IN_RESPONSE_TO.get(), inResponseTo);
+        }
+
+        XMLGregorianCalendar notBefore = subjectConfirmationData.getNotBefore();
+        if (notBefore != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.NOT_BEFORE.get(), notBefore.toString());
+        }
+
+        XMLGregorianCalendar notOnOrAfter = subjectConfirmationData.getNotOnOrAfter();
+        if (notOnOrAfter != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.NOT_ON_OR_AFTER.get(), notOnOrAfter.toString());
+        }
+
+        String recipient = subjectConfirmationData.getRecipient();
+        if (StringUtil.isNotNull(recipient)) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.RECIPIENT.get(), recipient);
+        }
+
+        String address = subjectConfirmationData.getAddress();
+        if (StringUtil.isNotNull(address)) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.ADDRESS.get(), address);
+        }
+
+        if (subjectConfirmationData instanceof KeyInfoConfirmationDataType) {
+            KeyInfoConfirmationDataType kicd = (KeyInfoConfirmationDataType) subjectConfirmationData;
+            KeyInfoType keyInfo = (KeyInfoType) kicd.getAnyType();
+            StaxWriterUtil.writeKeyInfo(writer, keyInfo);
+            /*
+             * if (keyInfo.getContent() == null || keyInfo.getContent().size() == 0) throw new
+             * ProcessingException(ErrorCodes.WRITER_INVALID_KEYINFO_NULL_CONTENT); StaxUtil.writeStartElement(this.writer,
+             * WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.KEYINFO, WSTrustConstants.XMLDSig.DSIG_NS);
+             * StaxUtil.writeNameSpace(this.writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.DSIG_NS); //
+             * write the keyInfo content. Object content = keyInfo.getContent().get(0); if (content instanceof Element) {
+             * Element element = (Element) keyInfo.getContent().get(0); StaxUtil.writeDOMNode(this.writer, element); } else if
+             * (content instanceof X509DataType) { X509DataType type = (X509DataType) content; if (type.getDataObjects().size()
+             * == 0) throw new ProcessingException(ErrorCodes.WRITER_NULL_VALUE + "X509Data");
+             * StaxUtil.writeStartElement(this.writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.X509DATA,
+             * WSTrustConstants.XMLDSig.DSIG_NS); Object obj = type.getDataObjects().get(0); if (obj instanceof Element) {
+             * Element element = (Element) obj; StaxUtil.writeDOMElement(this.writer, element); } else if (obj instanceof
+             * X509CertificateType) { X509CertificateType cert = (X509CertificateType) obj;
+             * StaxUtil.writeStartElement(this.writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.X509CERT,
+             * WSTrustConstants.XMLDSig.DSIG_NS); StaxUtil.writeCharacters(this.writer, new
+             * String(cert.getEncodedCertificate())); StaxUtil.writeEndElement(this.writer); }
+             * StaxUtil.writeEndElement(this.writer); } StaxUtil.writeEndElement(this.writer);
+             */
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    private void write(BaseIDAbstractType baseId) throws ProcessingException {
+        throw logger.notImplementedYet("Method not implemented.");
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriter.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriter.java
new file mode 100755
index 0000000..23a90d3
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriter.java
@@ -0,0 +1,289 @@
+/*
+ * JBoss, Home of Professional Open Source. Copyright 2008, Red Hat Middleware LLC, and individual contributors as
+ * indicated by the @author tags. See the copyright.txt file in the distribution for a full listing of individual
+ * contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any
+ * later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with this software; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF site:
+ * http://www.fsf.org.
+ */
+package org.keycloak.saml.processing.core.saml.v2.writers;
+
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.util.StaxUtil;
+import org.keycloak.dom.saml.v2.assertion.AdviceType;
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
+import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
+import org.keycloak.dom.saml.v2.assertion.AttributeStatementType.ASTChoiceType;
+import org.keycloak.dom.saml.v2.assertion.AttributeType;
+import org.keycloak.dom.saml.v2.assertion.AudienceRestrictionType;
+import org.keycloak.dom.saml.v2.assertion.AuthnContextClassRefType;
+import org.keycloak.dom.saml.v2.assertion.AuthnContextDeclRefType;
+import org.keycloak.dom.saml.v2.assertion.AuthnContextDeclType;
+import org.keycloak.dom.saml.v2.assertion.AuthnContextType;
+import org.keycloak.dom.saml.v2.assertion.AuthnStatementType;
+import org.keycloak.dom.saml.v2.assertion.ConditionAbstractType;
+import org.keycloak.dom.saml.v2.assertion.ConditionsType;
+import org.keycloak.dom.saml.v2.assertion.EncryptedElementType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.assertion.StatementAbstractType;
+import org.keycloak.dom.saml.v2.assertion.SubjectType;
+import org.keycloak.dom.saml.v2.assertion.URIType;
+import org.w3c.dom.Element;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamWriter;
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+
+import static org.keycloak.saml.common.constants.JBossSAMLURIConstants.ASSERTION_NSURI;
+
+/**
+ * Write the SAML Assertion to stream
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Nov 2, 2010
+ */
+public class SAMLAssertionWriter extends BaseWriter {
+
+    public SAMLAssertionWriter(XMLStreamWriter writer) {
+        super(writer);
+    }
+
+    /**
+     * Write an {@code AssertionType} to stream
+     *
+     * @param assertion
+     *
+     * @throws org.keycloak.saml.common.exceptions.ProcessingException
+     */
+    public void write(AssertionType assertion) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.ASSERTION.get(), ASSERTION_NSURI.get());
+        StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, ASSERTION_NSURI.get());
+        StaxUtil.writeDefaultNameSpace(writer, ASSERTION_NSURI.get());
+
+        // Attributes
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ID.get(), assertion.getID());
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.VERSION.get(), assertion.getVersion());
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ISSUE_INSTANT.get(), assertion.getIssueInstant().toString());
+
+        NameIDType issuer = assertion.getIssuer();
+        if (issuer != null)
+            write(issuer, new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
+
+        Element sig = assertion.getSignature();
+        if (sig != null)
+            StaxUtil.writeDOMElement(writer, sig);
+
+        SubjectType subject = assertion.getSubject();
+        if (subject != null) {
+            write(subject);
+        }
+
+        ConditionsType conditions = assertion.getConditions();
+        if (conditions != null) {
+            StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.CONDITIONS.get(), ASSERTION_NSURI.get());
+
+            if (conditions.getNotBefore() != null) {
+                StaxUtil.writeAttribute(writer, JBossSAMLConstants.NOT_BEFORE.get(), conditions.getNotBefore().toString());
+            }
+
+            if (conditions.getNotOnOrAfter() != null) {
+                StaxUtil.writeAttribute(writer, JBossSAMLConstants.NOT_ON_OR_AFTER.get(), conditions.getNotOnOrAfter().toString());
+            }
+
+            List<ConditionAbstractType> typeOfConditions = conditions.getConditions();
+            if (typeOfConditions != null) {
+                for (ConditionAbstractType typeCondition : typeOfConditions) {
+                    if (typeCondition instanceof AudienceRestrictionType) {
+                        AudienceRestrictionType art = (AudienceRestrictionType) typeCondition;
+                        StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.AUDIENCE_RESTRICTION.get(),
+                                ASSERTION_NSURI.get());
+                        List<URI> audiences = art.getAudience();
+                        if (audiences != null) {
+                            for (URI audience : audiences) {
+                                StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.AUDIENCE.get(),
+                                        ASSERTION_NSURI.get());
+                                StaxUtil.writeCharacters(writer, audience.toString());
+                                StaxUtil.writeEndElement(writer);
+                            }
+                        }
+
+                        StaxUtil.writeEndElement(writer);
+                    }
+                }
+            }
+
+            StaxUtil.writeEndElement(writer);
+        }
+
+        AdviceType advice = assertion.getAdvice();
+        if (advice != null)
+            throw logger.notImplementedYet("Advice");
+
+        Set<StatementAbstractType> statements = assertion.getStatements();
+        if (statements != null) {
+            for (StatementAbstractType statement : statements) {
+                if (statement instanceof AuthnStatementType) {
+                    write((AuthnStatementType) statement, false);
+                } else if (statement instanceof AttributeStatementType) {
+                    write((AttributeStatementType) statement);
+                } else
+                    throw logger.writerUnknownTypeError(statement.getClass().getName());
+            }
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    /**
+     * Write an {@code StatementAbstractType} to stream
+     *
+     * @param statement
+     *
+     * @throws ProcessingException
+     */
+    public void write(StatementAbstractType statement) throws ProcessingException {
+        // TODO: handle this section
+        throw logger.notImplementedYet("NYI");
+    }
+
+    public void write(AttributeStatementType statement) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.ATTRIBUTE_STATEMENT.get(),
+                ASSERTION_NSURI.get());
+
+        List<ASTChoiceType> attributes = statement.getAttributes();
+        if (attributes != null) {
+            for (ASTChoiceType attr : attributes) {
+                AttributeType attributeType = attr.getAttribute();
+                if (attributeType != null) {
+                    write(attributeType);
+                }
+                EncryptedElementType encType = attr.getEncryptedAssertion();
+                if (encType != null)
+                    throw logger.notImplementedYet("EncryptedElementType");
+            }
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    /**
+     * Write an {@code AuthnStatementType} to stream
+     *
+     * @param authnStatement
+     *
+     * @throws ProcessingException
+     */
+    public void write(AuthnStatementType authnStatement, boolean includeNamespace) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.AUTHN_STATEMENT.get(), ASSERTION_NSURI.get());
+        if (includeNamespace) {
+            StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, ASSERTION_NSURI.get());
+            StaxUtil.writeDefaultNameSpace(writer, ASSERTION_NSURI.get());
+        }
+
+        XMLGregorianCalendar authnInstant = authnStatement.getAuthnInstant();
+        if (authnInstant != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.AUTHN_INSTANT.get(), authnInstant.toString());
+        }
+
+        String sessionIndex = authnStatement.getSessionIndex();
+
+        if (sessionIndex != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.SESSION_INDEX.get(), sessionIndex);
+        }
+
+        AuthnContextType authnContext = authnStatement.getAuthnContext();
+        if (authnContext != null)
+            write(authnContext);
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    /**
+     * Write an {@code AuthnContextType} to stream
+     *
+     * @param authContext
+     *
+     * @throws ProcessingException
+     */
+    public void write(AuthnContextType authContext) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.AUTHN_CONTEXT.get(), ASSERTION_NSURI.get());
+
+        AuthnContextType.AuthnContextTypeSequence sequence = authContext.getSequence();
+        if (sequence != null) {
+            AuthnContextClassRefType authnContextClassRefType = sequence.getClassRef();
+            if (authnContextClassRefType != null) {
+                StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.AUTHN_CONTEXT_CLASS_REF.get(),
+                        ASSERTION_NSURI.get());
+                StaxUtil.writeCharacters(writer, authnContextClassRefType.getValue().toASCIIString());
+                StaxUtil.writeEndElement(writer);
+            }
+
+            Set<URIType> uriTypes = sequence.getURIType();
+            if (uriTypes != null) {
+                for (URIType uriType : uriTypes) {
+                    if (uriType instanceof AuthnContextDeclType) {
+                        StaxUtil.writeStartElement(writer, ASSERTION_PREFIX,
+                                JBossSAMLConstants.AUTHN_CONTEXT_DECLARATION.get(), ASSERTION_NSURI.get());
+                        StaxUtil.writeCharacters(writer, uriType.getValue().toASCIIString());
+                        StaxUtil.writeEndElement(writer);
+                    }
+                    if (uriType instanceof AuthnContextDeclRefType) {
+                        StaxUtil.writeStartElement(writer, ASSERTION_PREFIX,
+                                JBossSAMLConstants.AUTHN_CONTEXT_DECLARATION_REF.get(), ASSERTION_NSURI.get());
+                        StaxUtil.writeCharacters(writer, uriType.getValue().toASCIIString());
+                        StaxUtil.writeEndElement(writer);
+                    }
+                }
+            }
+        }
+
+        Set<URI> authAuthorities = authContext.getAuthenticatingAuthority();
+        if (authAuthorities != null) {
+            for (URI aa : authAuthorities) {
+                StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.AUTHENTICATING_AUTHORITY.get(),
+                        ASSERTION_NSURI.get());
+                StaxUtil.writeCharacters(writer, aa.toASCIIString());
+                StaxUtil.writeEndElement(writer);
+            }
+        }
+
+        Set<URIType> uriTypes = authContext.getURIType();
+        for (URIType uriType : uriTypes) {
+            if (uriType instanceof AuthnContextClassRefType) {
+                StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.AUTHN_CONTEXT_CLASS_REF.get(),
+                        ASSERTION_NSURI.get());
+                StaxUtil.writeCharacters(writer, uriType.getValue().toString());
+                StaxUtil.writeEndElement(writer);
+            } else if (uriType instanceof AuthnContextDeclRefType) {
+                StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.AUTHN_CONTEXT_DECLARATION_REF.get(),
+                        ASSERTION_NSURI.get());
+                StaxUtil.writeCharacters(writer, uriType.getValue().toString());
+                StaxUtil.writeEndElement(writer);
+            } else if (uriType instanceof AuthnContextDeclType) {
+                StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.AUTHN_CONTEXT_DECLARATION.get(),
+                        ASSERTION_NSURI.get());
+                StaxUtil.writeCharacters(writer, uriType.getValue().toString());
+                StaxUtil.writeEndElement(writer);
+            }
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLRequestWriter.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLRequestWriter.java
new file mode 100755
index 0000000..a6bfbe7
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLRequestWriter.java
@@ -0,0 +1,335 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.keycloak.saml.processing.core.saml.v2.writers;
+
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.util.StaxUtil;
+import org.keycloak.saml.common.util.StringUtil;
+import org.keycloak.dom.saml.v2.assertion.AttributeType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.assertion.SubjectType;
+import org.keycloak.dom.saml.v2.protocol.ArtifactResolveType;
+import org.keycloak.dom.saml.v2.protocol.AttributeQueryType;
+import org.keycloak.dom.saml.v2.protocol.AuthnContextComparisonType;
+import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
+import org.keycloak.dom.saml.v2.protocol.LogoutRequestType;
+import org.keycloak.dom.saml.v2.protocol.NameIDPolicyType;
+import org.keycloak.dom.saml.v2.protocol.RequestedAuthnContextType;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamWriter;
+import java.net.URI;
+import java.util.List;
+
+import static org.keycloak.saml.common.constants.JBossSAMLURIConstants.ASSERTION_NSURI;
+import static org.keycloak.saml.common.constants.JBossSAMLURIConstants.PROTOCOL_NSURI;
+
+/**
+ * Writes a SAML2 Request Type to Stream
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Nov 2, 2010
+ */
+public class SAMLRequestWriter extends BaseWriter {
+
+    public SAMLRequestWriter(XMLStreamWriter writer) {
+        super(writer);
+    }
+
+    /**
+     * Write a {@code AuthnRequestType } to stream
+     *
+     * @param request
+     *
+     * @throws org.keycloak.saml.common.exceptions.ProcessingException
+     */
+    public void write(AuthnRequestType request) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.AUTHN_REQUEST.get(), PROTOCOL_NSURI.get());
+        StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, PROTOCOL_NSURI.get());
+        StaxUtil.writeDefaultNameSpace(writer, ASSERTION_NSURI.get());
+
+        // Attributes
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ID.get(), request.getID());
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.VERSION.get(), request.getVersion());
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ISSUE_INSTANT.get(), request.getIssueInstant().toString());
+
+        URI destination = request.getDestination();
+        if (destination != null)
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.DESTINATION.get(), destination.toASCIIString());
+
+        String consent = request.getConsent();
+        if (StringUtil.isNotNull(consent))
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.CONSENT.get(), consent);
+
+        URI assertionURL = request.getAssertionConsumerServiceURL();
+        if (assertionURL != null)
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.ASSERTION_CONSUMER_SERVICE_URL.get(),
+                    assertionURL.toASCIIString());
+
+        Boolean forceAuthn = request.isForceAuthn();
+        if (forceAuthn != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.FORCE_AUTHN.get(), forceAuthn.toString());
+        }
+
+        Boolean isPassive = request.isIsPassive();
+        if (isPassive != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.IS_PASSIVE.get(), isPassive.toString());
+        }
+
+        URI protocolBinding = request.getProtocolBinding();
+        if (protocolBinding != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.PROTOCOL_BINDING.get(), protocolBinding.toString());
+        }
+
+        Integer assertionIndex = request.getAssertionConsumerServiceIndex();
+        if (assertionIndex != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.ASSERTION_CONSUMER_SERVICE_INDEX.get(),
+                    assertionIndex.toString());
+        }
+
+        Integer attrIndex = request.getAttributeConsumingServiceIndex();
+        if (attrIndex != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.ATTRIBUTE_CONSUMING_SERVICE_INDEX.get(), attrIndex.toString());
+        }
+        String providerName = request.getProviderName();
+        if (StringUtil.isNotNull(providerName)) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.PROVIDER_NAME.get(), providerName);
+        }
+
+        NameIDType issuer = request.getIssuer();
+        if (issuer != null) {
+            write(issuer, new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
+        }
+
+        Element sig = request.getSignature();
+        if (sig != null) {
+            StaxUtil.writeDOMElement(writer, sig);
+        }
+
+        NameIDPolicyType nameIDPolicy = request.getNameIDPolicy();
+        if (nameIDPolicy != null) {
+            write(nameIDPolicy);
+        }
+
+        RequestedAuthnContextType requestedAuthnContext = request.getRequestedAuthnContext();
+        if (requestedAuthnContext != null) {
+            write(requestedAuthnContext);
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    /**
+     * Write a {@code LogoutRequestType} to stream
+     *
+     * @param logOutRequest
+     *
+     * @throws ProcessingException
+     */
+    public void write(LogoutRequestType logOutRequest) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.LOGOUT_REQUEST.get(), PROTOCOL_NSURI.get());
+
+        StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, PROTOCOL_NSURI.get());
+        StaxUtil.writeDefaultNameSpace(writer, ASSERTION_NSURI.get());
+
+        // Attributes
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ID.get(), logOutRequest.getID());
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.VERSION.get(), logOutRequest.getVersion());
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ISSUE_INSTANT.get(), logOutRequest.getIssueInstant().toString());
+
+        URI destination = logOutRequest.getDestination();
+        if (destination != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.DESTINATION.get(), destination.toASCIIString());
+        }
+
+        String consent = logOutRequest.getConsent();
+        if (StringUtil.isNotNull(consent))
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.CONSENT.get(), consent);
+
+        NameIDType issuer = logOutRequest.getIssuer();
+        write(issuer, new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
+
+        Element signature = logOutRequest.getSignature();
+        if (signature != null) {
+            StaxUtil.writeDOMElement(writer, signature);
+        }
+
+        NameIDType nameID = logOutRequest.getNameID();
+        if (nameID != null) {
+            write(nameID, new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.NAMEID.get(), ASSERTION_PREFIX));
+        }
+
+        List<String> sessionIndexes = logOutRequest.getSessionIndex();
+
+        for (String sessionIndex : sessionIndexes) {
+            StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.SESSION_INDEX.get(), PROTOCOL_NSURI.get());
+
+            StaxUtil.writeCharacters(writer, sessionIndex);
+
+            StaxUtil.writeEndElement(writer);
+            StaxUtil.flush(writer);
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    /**
+     * Write a {@code NameIDPolicyType} to stream
+     *
+     * @param nameIDPolicy
+     *
+     * @throws ProcessingException
+     */
+    public void write(NameIDPolicyType nameIDPolicy) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.NAMEID_POLICY.get(), PROTOCOL_NSURI.get());
+
+        URI format = nameIDPolicy.getFormat();
+        if (format != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.FORMAT.get(), format.toASCIIString());
+        }
+
+        String spNameQualifier = nameIDPolicy.getSPNameQualifier();
+        if (StringUtil.isNotNull(spNameQualifier)) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.SP_NAME_QUALIFIER.get(), spNameQualifier);
+        }
+
+        Boolean allowCreate = nameIDPolicy.isAllowCreate();
+        if (allowCreate != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.ALLOW_CREATE.get(), allowCreate.toString());
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    /**
+     * Write a {@code RequestedAuthnContextType} to stream
+     *
+     * @param requestedAuthnContextType
+     *
+     * @throws ProcessingException
+     */
+    public void write(RequestedAuthnContextType requestedAuthnContextType) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.REQUESTED_AUTHN_CONTEXT.get(), PROTOCOL_NSURI.get());
+
+        AuthnContextComparisonType comparison = requestedAuthnContextType.getComparison();
+
+        if (comparison != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.COMPARISON.get(), comparison.value());
+        }
+
+        List<String> authnContextClassRef = requestedAuthnContextType.getAuthnContextClassRef();
+
+        if (authnContextClassRef != null && !authnContextClassRef.isEmpty()) {
+            for (String classRef : authnContextClassRef) {
+                StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.AUTHN_CONTEXT_CLASS_REF.get(), ASSERTION_NSURI.get());
+                StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, ASSERTION_NSURI.get());
+                StaxUtil.writeCharacters(writer, classRef);
+                StaxUtil.writeEndElement(writer);
+            }
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    public void write(ArtifactResolveType request) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.ARTIFACT_RESOLVE.get(), PROTOCOL_NSURI.get());
+        StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, PROTOCOL_NSURI.get());
+        StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, ASSERTION_NSURI.get());
+        StaxUtil.writeDefaultNameSpace(writer, ASSERTION_NSURI.get());
+
+        // Attributes
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ID.get(), request.getID());
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.VERSION.get(), request.getVersion());
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ISSUE_INSTANT.get(), request.getIssueInstant().toString());
+
+        URI destination = request.getDestination();
+        if (destination != null)
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.DESTINATION.get(), destination.toASCIIString());
+
+        String consent = request.getConsent();
+        if (StringUtil.isNotNull(consent))
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.CONSENT.get(), consent);
+
+        NameIDType issuer = request.getIssuer();
+        if (issuer != null) {
+            write(issuer, new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
+        }
+        Element sig = request.getSignature();
+        if (sig != null) {
+            StaxUtil.writeDOMElement(writer, sig);
+        }
+        String artifact = request.getArtifact();
+        if (StringUtil.isNotNull(artifact)) {
+            StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.ARTIFACT.get(), PROTOCOL_NSURI.get());
+            StaxUtil.writeCharacters(writer, artifact);
+            StaxUtil.writeEndElement(writer);
+        }
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    public void write(AttributeQueryType request) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.ATTRIBUTE_QUERY.get(), PROTOCOL_NSURI.get());
+        StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, PROTOCOL_NSURI.get());
+        StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, ASSERTION_NSURI.get());
+        StaxUtil.writeDefaultNameSpace(writer, ASSERTION_NSURI.get());
+
+        // Attributes
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ID.get(), request.getID());
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.VERSION.get(), request.getVersion());
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ISSUE_INSTANT.get(), request.getIssueInstant().toString());
+
+        URI destination = request.getDestination();
+        if (destination != null)
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.DESTINATION.get(), destination.toASCIIString());
+
+        String consent = request.getConsent();
+        if (StringUtil.isNotNull(consent))
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.CONSENT.get(), consent);
+
+        NameIDType issuer = request.getIssuer();
+        if (issuer != null) {
+            write(issuer, new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
+        }
+        Element sig = request.getSignature();
+        if (sig != null) {
+            StaxUtil.writeDOMElement(writer, sig);
+        }
+        SubjectType subject = request.getSubject();
+        if (subject != null) {
+            write(subject);
+        }
+        List<AttributeType> attributes = request.getAttribute();
+        for (AttributeType attr : attributes) {
+            write(attr);
+        }
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLResponseWriter.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLResponseWriter.java
new file mode 100755
index 0000000..1c4d3a6
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLResponseWriter.java
@@ -0,0 +1,264 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.saml.v2.writers;
+
+import org.keycloak.saml.common.constants.JBossSAMLConstants;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.util.StaxUtil;
+import org.keycloak.saml.common.util.StringUtil;
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
+import org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.protocol.ArtifactResponseType;
+import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.keycloak.dom.saml.v2.protocol.StatusCodeType;
+import org.keycloak.dom.saml.v2.protocol.StatusDetailType;
+import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+import org.keycloak.dom.saml.v2.protocol.StatusType;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamWriter;
+import java.net.URI;
+import java.util.List;
+
+/**
+ * Write a SAML Response to stream
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Nov 2, 2010
+ */
+public class SAMLResponseWriter extends BaseWriter {
+
+    private final SAMLAssertionWriter assertionWriter;
+
+    public SAMLResponseWriter(XMLStreamWriter writer) {
+        super(writer);
+        this.assertionWriter = new SAMLAssertionWriter(writer);
+    }
+
+    /**
+     * Write a {@code ResponseType} to stream
+     *
+     * @param response
+     * @param out
+     *
+     * @throws org.keycloak.saml.common.exceptions.ProcessingException
+     */
+    public void write(ResponseType response) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.RESPONSE.get(), JBossSAMLURIConstants.PROTOCOL_NSURI.get());
+
+        StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, JBossSAMLURIConstants.PROTOCOL_NSURI.get());
+        StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, JBossSAMLURIConstants.ASSERTION_NSURI.get());
+
+        writeBaseAttributes(response);
+
+        NameIDType issuer = response.getIssuer();
+        if (issuer != null) {
+            write(issuer, new QName(JBossSAMLURIConstants.ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
+        }
+
+        Element sig = response.getSignature();
+        if (sig != null) {
+            StaxUtil.writeDOMElement(writer, sig);
+        }
+
+        StatusType status = response.getStatus();
+        write(status);
+
+        List<ResponseType.RTChoiceType> choiceTypes = response.getAssertions();
+        if (choiceTypes != null) {
+            for (ResponseType.RTChoiceType choiceType : choiceTypes) {
+                AssertionType assertion = choiceType.getAssertion();
+                if (assertion != null) {
+                    assertionWriter.write(assertion);
+                }
+
+                EncryptedAssertionType encryptedAssertion = choiceType.getEncryptedAssertion();
+                if (encryptedAssertion != null) {
+                    Element encElement = encryptedAssertion.getEncryptedElement();
+                    StaxUtil.writeDOMElement(writer, encElement);
+                }
+            }
+        }
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    public void write(ArtifactResponseType response) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.ARTIFACT_RESPONSE.get(), JBossSAMLURIConstants.PROTOCOL_NSURI.get());
+
+        StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, JBossSAMLURIConstants.PROTOCOL_NSURI.get());
+        StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, JBossSAMLURIConstants.ASSERTION_NSURI.get());
+        StaxUtil.writeDefaultNameSpace(writer, JBossSAMLURIConstants.ASSERTION_NSURI.get());
+
+        writeBaseAttributes(response);
+
+        NameIDType issuer = response.getIssuer();
+        if (issuer != null) {
+            write(issuer, new QName(JBossSAMLURIConstants.ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
+        }
+
+        Element sig = response.getSignature();
+        if (sig != null) {
+            StaxUtil.writeDOMElement(writer, sig);
+        }
+
+        StatusType status = response.getStatus();
+        if (status != null) {
+            write(status);
+        }
+        Object anyObj = response.getAny();
+        if (anyObj instanceof AuthnRequestType) {
+            AuthnRequestType authn = (AuthnRequestType) anyObj;
+            SAMLRequestWriter requestWriter = new SAMLRequestWriter(writer);
+            requestWriter.write(authn);
+        } else if (anyObj instanceof ResponseType) {
+            ResponseType rt = (ResponseType) anyObj;
+            write(rt);
+        }
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    /**
+     * Write a {@code StatusResponseType}
+     *
+     * @param response
+     * @param qname QName of the starting element
+     * @param out
+     *
+     * @throws ProcessingException
+     */
+    public void write(StatusResponseType response, QName qname) throws ProcessingException {
+        if (qname == null) {
+            StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.STATUS_RESPONSE_TYPE.get(),
+                    JBossSAMLURIConstants.PROTOCOL_NSURI.get());
+        } else {
+            StaxUtil.writeStartElement(writer, qname.getPrefix(), qname.getLocalPart(), qname.getNamespaceURI());
+        }
+
+        StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, JBossSAMLURIConstants.PROTOCOL_NSURI.get());
+        StaxUtil.writeDefaultNameSpace(writer, JBossSAMLURIConstants.ASSERTION_NSURI.get());
+
+        writeBaseAttributes(response);
+
+        NameIDType issuer = response.getIssuer();
+        write(issuer, new QName(JBossSAMLURIConstants.ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
+
+        StatusType status = response.getStatus();
+        write(status);
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    /**
+     * Write a {@code StatusType} to stream
+     *
+     * @param status
+     * @param out
+     *
+     * @throws ProcessingException
+     */
+    public void write(StatusType status) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.STATUS.get(), JBossSAMLURIConstants.PROTOCOL_NSURI.get());
+
+        StatusCodeType statusCodeType = status.getStatusCode();
+        write(statusCodeType);
+
+        String statusMessage = status.getStatusMessage();
+        if (StringUtil.isNotNull(statusMessage)) {
+            StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.STATUS_MESSAGE.get(), JBossSAMLURIConstants.PROTOCOL_NSURI.get());
+            StaxUtil.writeEndElement(writer);
+        }
+
+        StatusDetailType statusDetail = status.getStatusDetail();
+        if (statusDetail != null)
+            write(statusDetail);
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    /**
+     * Write a {@code StatusCodeType} to stream
+     *
+     * @param statusCodeType
+     * @param out
+     *
+     * @throws ProcessingException
+     */
+    public void write(StatusCodeType statusCodeType) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.STATUS_CODE.get(), JBossSAMLURIConstants.PROTOCOL_NSURI.get());
+
+        URI value = statusCodeType.getValue();
+        if (value != null) {
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.VALUE.get(), value.toASCIIString());
+        }
+        StatusCodeType subStatusCode = statusCodeType.getStatusCode();
+        if (subStatusCode != null)
+            write(subStatusCode);
+
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    /**
+     * Write a {@code StatusDetailType} to stream
+     *
+     * @param statusDetailType
+     * @param out
+     *
+     * @throws ProcessingException
+     */
+    public void write(StatusDetailType statusDetailType) throws ProcessingException {
+        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.STATUS_CODE.get(), JBossSAMLURIConstants.PROTOCOL_NSURI.get());
+        StaxUtil.writeEndElement(writer);
+        StaxUtil.flush(writer);
+    }
+
+    /**
+     * Write the common attributes for all response types
+     *
+     * @param statusResponse
+     *
+     * @throws ProcessingException
+     */
+    private void writeBaseAttributes(StatusResponseType statusResponse) throws ProcessingException {
+        // Attributes
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ID.get(), statusResponse.getID());
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.VERSION.get(), statusResponse.getVersion());
+        StaxUtil.writeAttribute(writer, JBossSAMLConstants.ISSUE_INSTANT.get(), statusResponse.getIssueInstant().toString());
+
+        String destination = statusResponse.getDestination();
+        if (StringUtil.isNotNull(destination))
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.DESTINATION.get(), destination);
+
+        String consent = statusResponse.getConsent();
+        if (StringUtil.isNotNull(consent))
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.CONSENT.get(), consent);
+
+        String inResponseTo = statusResponse.getInResponseTo();
+        if (StringUtil.isNotNull(inResponseTo))
+            StaxUtil.writeAttribute(writer, JBossSAMLConstants.IN_RESPONSE_TO.get(), inResponseTo);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/CoreConfigUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/CoreConfigUtil.java
new file mode 100755
index 0000000..4aa2819
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/CoreConfigUtil.java
@@ -0,0 +1,208 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.util;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.dom.saml.v2.metadata.EndpointType;
+import org.keycloak.dom.saml.v2.metadata.EntitiesDescriptorType;
+import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType;
+import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType.EDTChoiceType;
+import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType.EDTDescriptorChoiceType;
+import org.keycloak.dom.saml.v2.metadata.IDPSSODescriptorType;
+import org.keycloak.dom.saml.v2.metadata.IndexedEndpointType;
+import org.keycloak.dom.saml.v2.metadata.SPSSODescriptorType;
+import java.util.List;
+
+/**
+ * Utility for configuration
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Nov 13, 2009
+ */
+public class CoreConfigUtil {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * Get the first metadata descriptor for an IDP
+     *
+     * @param entitiesDescriptor
+     *
+     * @return
+     */
+    public static IDPSSODescriptorType getIDPDescriptor(EntitiesDescriptorType entitiesDescriptor) {
+        IDPSSODescriptorType idp = null;
+        List<Object> entitiesList = entitiesDescriptor.getEntityDescriptor();
+        for (Object theObject : entitiesList) {
+            if (theObject instanceof EntitiesDescriptorType) {
+                idp = getIDPDescriptor((EntitiesDescriptorType) theObject);
+            } else if (theObject instanceof EntityDescriptorType) {
+                idp = getIDPDescriptor((EntityDescriptorType) theObject);
+            }
+            if (idp != null) {
+                break;
+            }
+        }
+        return idp;
+    }
+
+    /**
+     * Get the IDP metadata descriptor from an entity descriptor
+     *
+     * @param entityDescriptor
+     *
+     * @return
+     */
+    public static IDPSSODescriptorType getIDPDescriptor(EntityDescriptorType entityDescriptor) {
+        List<EDTChoiceType> edtChoices = entityDescriptor.getChoiceType();
+        for (EDTChoiceType edt : edtChoices) {
+            List<EDTDescriptorChoiceType> edtDescriptors = edt.getDescriptors();
+            for (EDTDescriptorChoiceType edtDesc : edtDescriptors) {
+                IDPSSODescriptorType idpSSO = edtDesc.getIdpDescriptor();
+                if (idpSSO != null) {
+                    return idpSSO;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get the SP Descriptor from an entity descriptor
+     *
+     * @param entityDescriptor
+     *
+     * @return
+     */
+    public static SPSSODescriptorType getSPDescriptor(EntityDescriptorType entityDescriptor) {
+        List<EDTChoiceType> edtChoices = entityDescriptor.getChoiceType();
+        for (EDTChoiceType edt : edtChoices) {
+            List<EDTDescriptorChoiceType> edtDescriptors = edt.getDescriptors();
+            for (EDTDescriptorChoiceType edtDesc : edtDescriptors) {
+                SPSSODescriptorType spSSO = edtDesc.getSpDescriptor();
+                if (spSSO != null) {
+                    return spSSO;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Given a binding uri, get the IDP identity url
+     *
+     * @param idp
+     * @param bindingURI
+     *
+     * @return
+     */
+    public static String getIdentityURL(IDPSSODescriptorType idp, String bindingURI) {
+        String identityURL = null;
+
+        List<EndpointType> endpoints = idp.getSingleSignOnService();
+        for (EndpointType endpoint : endpoints) {
+            if (endpoint.getBinding().toString().equals(bindingURI)) {
+                identityURL = endpoint.getLocation().toString();
+                break;
+            }
+
+        }
+        return identityURL;
+    }
+
+    /**
+     * Given a binding uri, get the IDP identity url
+     *
+     * @param idp
+     * @param bindingURI
+     *
+     * @return
+     */
+    public static String getLogoutURL(IDPSSODescriptorType idp, String bindingURI) {
+        String logoutURL = null;
+
+        List<EndpointType> endpoints = idp.getSingleLogoutService();
+        for (EndpointType endpoint : endpoints) {
+            if (endpoint.getBinding().toString().equals(bindingURI)) {
+                logoutURL = endpoint.getLocation().toString();
+                break;
+            }
+
+        }
+        return logoutURL;
+    }
+
+    /**
+     * Given a binding uri, get the IDP logout response url (used for global logouts)
+     */
+    public static String getLogoutResponseLocation(IDPSSODescriptorType idp, String bindingURI) {
+        String logoutResponseLocation = null;
+
+        List<EndpointType> endpoints = idp.getSingleLogoutService();
+        for (EndpointType endpoint : endpoints) {
+            if (endpoint.getBinding().toString().equals(bindingURI)) {
+                if (endpoint.getResponseLocation() != null) {
+                    logoutResponseLocation = endpoint.getResponseLocation().toString();
+                } else {
+                    logoutResponseLocation = null;
+                }
+
+                break;
+            }
+
+        }
+        return logoutResponseLocation;
+    }
+
+    /**
+     * Get the service url for the SP
+     *
+     * @param sp
+     * @param bindingURI
+     *
+     * @return
+     */
+    public static String getServiceURL(SPSSODescriptorType sp, String bindingURI) {
+        String serviceURL = null;
+
+        List<IndexedEndpointType> endpoints = sp.getAssertionConsumerService();
+        for (IndexedEndpointType endpoint : endpoints) {
+            if (endpoint.getBinding().toString().equals(bindingURI)) {
+                serviceURL = endpoint.getLocation().toString();
+                break;
+            }
+
+        }
+        return serviceURL;
+    }
+
+    private static void addAllEntityDescriptorsRecursively(List<EntityDescriptorType> resultList,
+                                                           EntitiesDescriptorType entitiesDescriptorType) {
+        List<Object> entities = entitiesDescriptorType.getEntityDescriptor();
+        for (Object o : entities) {
+            if (o instanceof EntitiesDescriptorType) {
+                addAllEntityDescriptorsRecursively(resultList, (EntitiesDescriptorType) o);
+            } else if (o instanceof EntityDescriptorType) {
+                resultList.add((EntityDescriptorType) o);
+            } else {
+                throw new IllegalArgumentException("Wrong type: " + o.getClass());
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/EncryptionKeyUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/EncryptionKeyUtil.java
new file mode 100755
index 0000000..850997d
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/EncryptionKeyUtil.java
@@ -0,0 +1,50 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.util;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import java.security.GeneralSecurityException;
+
+/**
+ * Utility to generate symmetric key
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Feb 4, 2009
+ */
+public class EncryptionKeyUtil {
+
+    /**
+     * Generate a secret key useful for encryption/decryption
+     *
+     * @param encAlgo
+     * @param keySize Length of the key (if 0, defaults to 128 bits)
+     *
+     * @return
+     *
+     * @throws GeneralSecurityException
+     */
+    public static SecretKey getSecretKey(String encAlgo, int keySize) throws GeneralSecurityException {
+        KeyGenerator keyGenerator = KeyGenerator.getInstance(encAlgo);
+        if (keySize == 0)
+            keySize = 128;
+        keyGenerator.init(keySize);
+        return keyGenerator.generateKey();
+    }
+
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/IDFedLSInputResolver.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/IDFedLSInputResolver.java
new file mode 100755
index 0000000..99b5a3c
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/IDFedLSInputResolver.java
@@ -0,0 +1,224 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.util;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.util.StringUtil;
+import org.w3c.dom.ls.LSInput;
+import org.w3c.dom.ls.LSResourceResolver;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.URL;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * An LSResource Resolver for schema validation
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jun 9, 2009
+ */
+public class IDFedLSInputResolver implements LSResourceResolver {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    private static Map<String, LSInput> lsmap = new HashMap<String, LSInput>();
+
+    private static Map<String, String> schemaLocationMap = new LinkedHashMap<String, String>();
+
+    static {
+        // XML Schema/DTD
+        schemaLocationMap.put("datatypes.dtd", "schema/w3c/xmlschema/datatypes.dtd");
+        schemaLocationMap.put("XMLSchema.dtd", "schema/w3c/xmlschema/XMLSchema.dtd");
+        schemaLocationMap.put("http://www.w3.org/2001/xml.xsd", "schema/w3c/xmlschema/xml.xsd");
+
+        // XML DSIG
+        schemaLocationMap.put("http://www.w3.org/2000/09/xmldsig#", "schema/w3c/xmldsig/xmldsig-core-schema.xsd");
+        schemaLocationMap.put("http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd",
+                "schema/w3c/xmldsig/xmldsig-core-schema.xsd");
+
+        // XML Enc
+        schemaLocationMap.put("http://www.w3.org/2001/04/xmlenc#", "schema/w3c/xmlenc/xenc-schema.xsd");
+        schemaLocationMap.put("http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/xenc-schema.xsd",
+                "schema/w3c/xmlenc/xenc-schema.xsd");
+
+        // XACML
+        schemaLocationMap.put("access_control-xacml-2.0-context-schema-os.xsd",
+                "schema/access_control-xacml-2.0-context-schema-os.xsd");
+        schemaLocationMap.put("access_control-xacml-2.0-policy-schema-os.xsd",
+                "schema/access_control-xacml-2.0-policy-schema-os.xsd");
+
+        // SAML
+
+        schemaLocationMap.put("saml-schema-assertion-2.0.xsd", "schema/saml/v2/saml-schema-assertion-2.0.xsd");
+        schemaLocationMap.put("saml-schema-protocol-2.0.xsd", "schema/saml/v2/saml-schema-protocol-2.0.xsd");
+        schemaLocationMap.put("saml-schema-metadata-2.0.xsd", "schema/saml/v2/saml-schema-metadata-2.0.xsd");
+        schemaLocationMap.put("saml-schema-x500-2.0.xsd", "schema/saml/v2/saml-schema-x500-2.0.xsd");
+        schemaLocationMap.put("saml-schema-xacml-2.0.xsd", "schema/saml/v2/saml-schema-xacml-2.0.xsd");
+        schemaLocationMap.put("saml-schema-xacml-2.0.xsd", "schema/saml/v2/saml-schema-xacml-2.0.xsd");
+        schemaLocationMap.put("saml-schema-authn-context-2.0.xsd", "schema/saml/v2/saml-schema-authn-context-2.0.xsd");
+        schemaLocationMap.put("saml-schema-authn-context-types-2.0.xsd",
+                "schema/saml/v2/saml-schema-authn-context-types-2.0.xsd");
+
+        schemaLocationMap.put("saml-schema-assertion-1.0.xsd", "schema/saml/v1/saml-schema-assertion-1.0.xsd");
+        schemaLocationMap.put("oasis-sstc-saml-schema-assertion-1.1.xsd",
+                "schema/saml/v1/oasis-sstc-saml-schema-assertion-1.1.xsd");
+        schemaLocationMap.put("saml-schema-protocol-1.1.xsd", "schema/saml/v1/saml-schema-protocol-1.1.xsd");
+
+        schemaLocationMap.put("access_control-xacml-2.0-saml-assertion-schema-os.xsd",
+                "schema/saml/v2/access_control-xacml-2.0-saml-assertion-schema-os.xsd");
+
+        schemaLocationMap.put("access_control-xacml-2.0-saml-protocol-schema-os.xsd",
+                "schema/saml/v2/access_control-xacml-2.0-saml-protocol-schema-os.xsd");
+
+        // WS-T
+        schemaLocationMap.put("http://docs.oasis-open.org/ws-sx/ws-trust/200512", "schema/wstrust/v1_3/ws-trust-1.3.xsd");
+        schemaLocationMap.put("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
+                "schema/wstrust/v1_3/oasis-200401-wss-wssecurity-secext-1.0.xsd");
+        schemaLocationMap.put("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd",
+                "schema/wstrust/v1_3/oasis-200401-wss-wssecurity-utility-1.0.xsd");
+        schemaLocationMap.put("http://schemas.xmlsoap.org/ws/2004/09/policy", "schema/wstrust/v1_3/ws-policy.xsd");
+        schemaLocationMap.put("http://www.w3.org/2005/08/addressing", "schema/wstrust/v1_3/ws-addr.xsd");
+    }
+
+    public static Collection<String> schemas() {
+        Collection<String> schemaValues = schemaLocationMap.values();
+        schemaValues.remove("schema/w3c/xmlschema/datatypes.dtd");
+        schemaValues.remove("schema/w3c/xmlschema/XMLSchema.dtd");
+        logger.info("Considered the schemas:" + schemaValues);
+        return schemaValues;
+    }
+
+    public LSInput resolveResource(String type, String namespaceURI, final String publicId, final String systemId,
+                                   final String baseURI) {
+        LSInput lsi = null;
+        if (systemId == null)
+            throw logger.nullValueError("systemid");
+        if (StringUtil.isNotNull(systemId) && systemId.endsWith("dtd") && StringUtil.isNotNull(baseURI)) {
+            lsi = lsmap.get(baseURI);
+        }
+        if (lsi == null)
+            lsi = lsmap.get(systemId);
+        if (lsi == null) {
+            final String loc = schemaLocationMap.get(systemId);
+            if (loc == null)
+                return null;
+
+            lsi = new PicketLinkLSInput(baseURI, loc, publicId, systemId);
+
+            logger.trace("Loaded:" + lsi);
+
+            lsmap.put(systemId, lsi);
+        }
+        return lsi;
+    }
+
+    public static class PicketLinkLSInput implements LSInput {
+
+        private final String baseURI;
+
+        private final String loc;
+
+        private final String publicId;
+
+        private final String systemId;
+
+        public PicketLinkLSInput(String baseURI, String loc, String publicID, String systemID) {
+            this.baseURI = baseURI;
+            this.loc = loc;
+            this.publicId = publicID;
+            this.systemId = systemID;
+        }
+
+        public String getBaseURI() {
+            return baseURI;
+        }
+
+        public InputStream getByteStream() {
+            URL url = SecurityActions.loadResource(getClass(), loc);
+            InputStream is;
+            try {
+                is = url.openStream();
+            } catch (IOException e) {
+                throw new RuntimeException(logger.classNotLoadedError(loc));
+            }
+            if (is == null)
+                throw logger.nullValueError("inputstream is null for " + loc);
+            return is;
+        }
+
+        public boolean getCertifiedText() {
+            return false;
+        }
+
+        public Reader getCharacterStream() {
+            return null;
+        }
+
+        public String getEncoding() {
+            return null;
+        }
+
+        public String getPublicId() {
+            return publicId;
+        }
+
+        public String getStringData() {
+            return null;
+        }
+
+        public String getSystemId() {
+            return systemId;
+        }
+
+        public void setBaseURI(String baseURI) {
+        }
+
+        public void setByteStream(InputStream byteStream) {
+        }
+
+        public void setCertifiedText(boolean certifiedText) {
+        }
+
+        public void setCharacterStream(Reader characterStream) {
+        }
+
+        public void setEncoding(String encoding) {
+        }
+
+        public void setPublicId(String publicId) {
+        }
+
+        public void setStringData(String stringData) {
+        }
+
+        public void setSystemId(String systemId) {
+        }
+
+        @Override
+        public String toString() {
+            return "PicketLinkLSInput [baseURI=" + baseURI + ", loc=" + loc + ", publicId=" + publicId + ", systemId="
+                    + systemId + "]";
+        }
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXBUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXBUtil.java
new file mode 100755
index 0000000..2c3ad47
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXBUtil.java
@@ -0,0 +1,280 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.util;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+
+/**
+ * Utility to obtain JAXB2 marshaller/unmarshaller etc
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since May 26, 2009
+ */
+public class JAXBUtil {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    public static final String W3C_XML_SCHEMA_NS_URI = "http://www.w3.org/2001/XMLSchema";
+
+    private static HashMap<String, JAXBContext> jaxbContextHash = new HashMap<String, JAXBContext>();
+
+    static {
+        // Useful on Sun VMs. Harmless on other VMs.
+        SecurityActions.setSystemProperty("com.sun.xml.bind.v2.runtime.JAXBContextImpl.fastBoot", "true");
+    }
+
+    /**
+     * Get the JAXB Marshaller
+     *
+     * @param pkgName The package name for the jaxb context
+     * @param schemaLocation location of the schema to validate against
+     *
+     * @return Marshaller
+     *
+     * @throws JAXBException
+     * @throws SAXException
+     */
+    public static Marshaller getValidatingMarshaller(String pkgName, String schemaLocation) throws JAXBException, SAXException {
+        Marshaller marshaller = getMarshaller(pkgName);
+
+        // Validate against schema
+        Schema schema = getJAXPSchemaInstance(schemaLocation);
+        marshaller.setSchema(schema);
+
+        return marshaller;
+    }
+
+    /**
+     * Get the JAXB Marshaller
+     *
+     * @param pkgName The package name for the jaxb context
+     *
+     * @return Marshaller
+     *
+     * @throws JAXBException
+     */
+    public static Marshaller getMarshaller(String pkgName) throws JAXBException {
+        if (pkgName == null)
+            throw logger.nullArgumentError("pkgName");
+
+        JAXBContext jc = getJAXBContext(pkgName);
+        Marshaller marshaller = jc.createMarshaller();
+        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
+        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE); // Breaks signatures
+        return marshaller;
+    }
+
+    /**
+     * Get the JAXB Unmarshaller
+     *
+     * @param pkgName The package name for the jaxb context
+     *
+     * @return unmarshaller
+     *
+     * @throws JAXBException
+     */
+    public static Unmarshaller getUnmarshaller(String pkgName) throws JAXBException {
+        if (pkgName == null)
+            throw logger.nullArgumentError("pkgName");
+        JAXBContext jc = getJAXBContext(pkgName);
+        return jc.createUnmarshaller();
+    }
+
+    /**
+     * Get the JAXB Unmarshaller for a selected set of package names
+     *
+     * @param pkgNames
+     *
+     * @return
+     *
+     * @throws JAXBException
+     */
+    public static Unmarshaller getUnmarshaller(String... pkgNames) throws JAXBException {
+        if (pkgNames == null)
+            throw logger.nullArgumentError("pkgName");
+        int len = pkgNames.length;
+        if (len == 0)
+            return getUnmarshaller(pkgNames[0]);
+
+        JAXBContext jc = getJAXBContext(pkgNames);
+        return jc.createUnmarshaller();
+    }
+
+    /**
+     * Get the JAXB Unmarshaller
+     *
+     * @param pkgName The package name for the jaxb context
+     * @param schemaLocation location of the schema to validate against
+     *
+     * @return unmarshaller
+     *
+     * @throws JAXBException
+     * @throws SAXException
+     */
+    public static Unmarshaller getValidatingUnmarshaller(String pkgName, String schemaLocation) throws JAXBException,
+            SAXException {
+        Unmarshaller unmarshaller = getUnmarshaller(pkgName);
+        Schema schema = getJAXPSchemaInstance(schemaLocation);
+        unmarshaller.setSchema(schema);
+
+        return unmarshaller;
+    }
+
+    public static Unmarshaller getValidatingUnmarshaller(String[] pkgNames, String[] schemaLocations) throws JAXBException,
+            SAXException, IOException {
+        StringBuilder builder = new StringBuilder();
+        int len = pkgNames.length;
+        if (len == 0)
+            throw logger.nullValueError("Packages are empty");
+
+        for (String pkg : pkgNames) {
+            builder.append(pkg);
+            builder.append(":");
+        }
+
+        Unmarshaller unmarshaller = getUnmarshaller(builder.toString());
+
+        SchemaFactory schemaFactory = getSchemaFactory();
+
+        // Get the sources
+        Source[] schemaSources = new Source[schemaLocations.length];
+
+        int i = 0;
+        for (String schemaLocation : schemaLocations) {
+            URL schemaURL = SecurityActions.loadResource(JAXBUtil.class, schemaLocation);
+            if (schemaURL == null)
+                throw logger.nullValueError("Schema URL :" + schemaLocation);
+
+            schemaSources[i++] = new StreamSource(schemaURL.openStream());
+        }
+
+        Schema schema = schemaFactory.newSchema(schemaSources);
+        unmarshaller.setSchema(schema);
+
+        return unmarshaller;
+    }
+
+    private static Schema getJAXPSchemaInstance(String schemaLocation) throws SAXException {
+        URL schemaURL = SecurityActions.loadResource(JAXBUtil.class, schemaLocation);
+        if (schemaURL == null)
+            throw logger.nullValueError("Schema URL :" + schemaLocation);
+        SchemaFactory scFact = getSchemaFactory();
+        Schema schema = scFact.newSchema(schemaURL);
+        return schema;
+    }
+
+    private static SchemaFactory getSchemaFactory() {
+        SchemaFactory scFact = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
+
+        // Always install the resolver unless the system property is set
+        if (SecurityActions.getSystemProperty("org.picketlink.identity.federation.jaxb.ls", null) == null)
+            scFact.setResourceResolver(new IDFedLSInputResolver());
+
+        scFact.setErrorHandler(new ErrorHandler() {
+            public void error(SAXParseException exception) throws SAXException {
+                StringBuilder builder = new StringBuilder();
+                builder.append("Line Number=").append(exception.getLineNumber());
+                builder.append(" Col Number=").append(exception.getColumnNumber());
+                builder.append(" Public ID=").append(exception.getPublicId());
+                builder.append(" System ID=").append(exception.getSystemId());
+                builder.append(" exc=").append(exception.getLocalizedMessage());
+
+                logger.trace("SAX Error:" + builder.toString());
+            }
+
+            public void fatalError(SAXParseException exception) throws SAXException {
+                StringBuilder builder = new StringBuilder();
+                builder.append("Line Number=").append(exception.getLineNumber());
+                builder.append(" Col Number=").append(exception.getColumnNumber());
+                builder.append(" Public ID=").append(exception.getPublicId());
+                builder.append(" System ID=").append(exception.getSystemId());
+                builder.append(" exc=").append(exception.getLocalizedMessage());
+
+                logger.error("SAX Fatal Error:" + builder.toString());
+            }
+
+            public void warning(SAXParseException exception) throws SAXException {
+                StringBuilder builder = new StringBuilder();
+                builder.append("Line Number=").append(exception.getLineNumber());
+                builder.append(" Col Number=").append(exception.getColumnNumber());
+                builder.append(" Public ID=").append(exception.getPublicId());
+                builder.append(" System ID=").append(exception.getSystemId());
+                builder.append(" exc=").append(exception.getLocalizedMessage());
+
+                logger.trace("SAX Warn:" + builder.toString());
+            }
+        });
+        return scFact;
+    }
+
+    public static JAXBContext getJAXBContext(String path) throws JAXBException {
+        JAXBContext jx = jaxbContextHash.get(path);
+        if (jx == null) {
+            jx = JAXBContext.newInstance(path);
+            jaxbContextHash.put(path, jx);
+        }
+        return jx;
+    }
+
+    public static JAXBContext getJAXBContext(String... paths) throws JAXBException {
+        int len = paths.length;
+        if (len == 0)
+            return getJAXBContext(paths[0]);
+
+        StringBuilder builder = new StringBuilder();
+        for (String path : paths) {
+            builder.append(path).append(":");
+        }
+
+        String finalPath = builder.toString();
+
+        JAXBContext jx = jaxbContextHash.get(finalPath);
+        if (jx == null) {
+            jx = JAXBContext.newInstance(finalPath);
+            jaxbContextHash.put(finalPath, jx);
+        }
+        return jx;
+    }
+
+    public static JAXBContext getJAXBContext(Class<?> clazz) throws JAXBException {
+        String clazzName = clazz.getName();
+
+        JAXBContext jx = jaxbContextHash.get(clazzName);
+        if (jx == null) {
+            jx = JAXBContext.newInstance(clazz);
+            jaxbContextHash.put(clazzName, jx);
+        }
+        return jx;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXPValidationUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXPValidationUtil.java
new file mode 100755
index 0000000..836b3fc
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXPValidationUtil.java
@@ -0,0 +1,168 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.util;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.util.DocumentUtil;
+import org.keycloak.saml.common.util.SystemPropertiesUtil;
+import org.w3c.dom.Node;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.List;
+
+/**
+ * Utility class associated with JAXP Validation
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jun 30, 2011
+ */
+public class JAXPValidationUtil {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    protected static Validator validator;
+
+    protected static SchemaFactory schemaFactory;
+
+    public static void validate(String str) throws SAXException, IOException {
+        validator().validate(new StreamSource(str));
+    }
+
+    public static void validate(InputStream stream) throws SAXException, IOException {
+        validator().validate(new StreamSource(stream));
+    }
+
+    /**
+     * Based on system property "picketlink.schema.validate" set to "true", do schema validation
+     *
+     * @param samlDocument
+     *
+     * @throws org.keycloak.saml.common.exceptions.ProcessingException
+     */
+    public static void checkSchemaValidation(Node samlDocument) throws ProcessingException {
+        if (SecurityActions.getSystemProperty("picketlink.schema.validate", "false").equalsIgnoreCase("true")) {
+            try {
+                JAXPValidationUtil.validate(DocumentUtil.getNodeAsStream(samlDocument));
+            } catch (Exception e) {
+                throw logger.processingError(e);
+            }
+        }
+    }
+
+    public static Validator validator() throws SAXException, IOException {
+        SystemPropertiesUtil.ensure();
+
+        if (validator == null) {
+            Schema schema = getSchema();
+            if (schema == null)
+                throw logger.nullValueError("schema");
+
+            validator = schema.newValidator();
+            validator.setErrorHandler(new CustomErrorHandler());
+        }
+        return validator;
+    }
+
+    private static Schema getSchema() throws IOException {
+        boolean tccl_jaxp = SystemPropertiesUtil.getSystemProperty(GeneralConstants.TCCL_JAXP, "false").equalsIgnoreCase("true");
+
+        ClassLoader prevTCCL = SecurityActions.getTCCL();
+        try {
+            if (tccl_jaxp) {
+                SecurityActions.setTCCL(JAXPValidationUtil.class.getClassLoader());
+            }
+            schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
+
+            schemaFactory.setResourceResolver(new IDFedLSInputResolver());
+            schemaFactory.setErrorHandler(new CustomErrorHandler());
+        } finally {
+            if (tccl_jaxp) {
+                SecurityActions.setTCCL(prevTCCL);
+            }
+        }
+        Schema schemaGrammar = null;
+        try {
+            schemaGrammar = schemaFactory.newSchema(sources());
+        } catch (SAXException e) {
+            logger.xmlCouldNotGetSchema(e);
+        }
+        return schemaGrammar;
+    }
+
+    private static Source[] sources() throws IOException {
+        List<String> schemas = SchemaManagerUtil.getSchemas();
+
+        Source[] sourceArr = new Source[schemas.size()];
+
+        int i = 0;
+        for (String schema : schemas) {
+            URL url = SecurityActions.loadResource(JAXPValidationUtil.class, schema);
+            if (url == null)
+                throw logger.nullValueError("schema url:" + schema);
+            sourceArr[i++] = new StreamSource(url.openStream());
+        }
+        return sourceArr;
+    }
+
+    private static class CustomErrorHandler implements ErrorHandler {
+
+        public void error(SAXParseException ex) throws SAXException {
+            logException(ex);
+            if (ex.getMessage().contains("null") == false) {
+                throw ex;
+            }
+        }
+
+        public void fatalError(SAXParseException ex) throws SAXException {
+            logException(ex);
+            throw ex;
+        }
+
+        public void warning(SAXParseException ex) throws SAXException {
+            logException(ex);
+        }
+
+        private void logException(SAXParseException sax) {
+            StringBuilder builder = new StringBuilder();
+
+            if (logger.isTraceEnabled()) {
+                builder.append("[line:").append(sax.getLineNumber()).append(",").append("::col=").append(sax.getColumnNumber())
+                        .append("]");
+                builder.append("[publicID:").append(sax.getPublicId()).append(",systemId=").append(sax.getSystemId())
+                        .append("]");
+                builder.append(":").append(sax.getLocalizedMessage());
+                logger.trace(builder.toString());
+            }
+        }
+    }
+
+    ;
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/KeyStoreUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/KeyStoreUtil.java
new file mode 100755
index 0000000..793f608
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/KeyStoreUtil.java
@@ -0,0 +1,187 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.util;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.Certificate;
+
+/**
+ * Utility to handle Java Keystore
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jan 12, 2009
+ */
+public class KeyStoreUtil {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * Get the KeyStore
+     *
+     * @param keyStoreFile
+     * @param storePass
+     *
+     * @return
+     *
+     * @throws GeneralSecurityException
+     * @throws IOException
+     */
+    public static KeyStore getKeyStore(File keyStoreFile, char[] storePass) throws GeneralSecurityException, IOException {
+        FileInputStream fis = new FileInputStream(keyStoreFile);
+        return getKeyStore(fis, storePass);
+    }
+
+    /**
+     * Get the Keystore given the url to the keystore file as a string
+     *
+     * @param fileURL
+     * @param storePass
+     *
+     * @return
+     *
+     * @throws GeneralSecurityException
+     * @throws IOException
+     */
+    public static KeyStore getKeyStore(String fileURL, char[] storePass) throws GeneralSecurityException, IOException {
+        if (fileURL == null)
+            throw logger.nullArgumentError("fileURL");
+
+        File file = new File(fileURL);
+        FileInputStream fis = new FileInputStream(file);
+        return getKeyStore(fis, storePass);
+    }
+
+    /**
+     * Get the Keystore given the URL to the keystore
+     *
+     * @param url
+     * @param storePass
+     *
+     * @return
+     *
+     * @throws GeneralSecurityException
+     * @throws IOException
+     */
+    public static KeyStore getKeyStore(URL url, char[] storePass) throws GeneralSecurityException, IOException {
+        if (url == null)
+            throw logger.nullArgumentError("url");
+
+        return getKeyStore(url.openStream(), storePass);
+    }
+
+    /**
+     * Get the Key Store <b>Note:</b> This method wants the InputStream to be not null.
+     *
+     * @param ksStream
+     * @param storePass
+     *
+     * @return
+     *
+     * @throws GeneralSecurityException
+     * @throws IOException
+     * @throws IllegalArgumentException if ksStream is null
+     */
+    public static KeyStore getKeyStore(InputStream ksStream, char[] storePass) throws GeneralSecurityException, IOException {
+        if (ksStream == null)
+            throw logger.nullArgumentError("InputStream for the KeyStore");
+        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+        ks.load(ksStream, storePass);
+        return ks;
+    }
+
+    /**
+     * Get the Public Key from the keystore
+     *
+     * @param ks
+     * @param alias
+     * @param password
+     *
+     * @return
+     *
+     * @throws GeneralSecurityException
+     */
+    public static PublicKey getPublicKey(KeyStore ks, String alias, char[] password) throws GeneralSecurityException {
+        PublicKey publicKey = null;
+
+        // Get private key
+        Key key = ks.getKey(alias, password);
+        if (key instanceof PrivateKey) {
+            // Get certificate of public key
+            Certificate cert = ks.getCertificate(alias);
+
+            // Get public key
+            publicKey = cert.getPublicKey();
+        }
+        // if alias is a certificate alias, get the public key from the certificate.
+        if (publicKey == null) {
+            Certificate cert = ks.getCertificate(alias);
+            if (cert != null)
+                publicKey = cert.getPublicKey();
+        }
+        return publicKey;
+    }
+
+    /**
+     * Add a certificate to the KeyStore
+     *
+     * @param keystoreFile
+     * @param storePass
+     * @param alias
+     * @param cert
+     *
+     * @throws GeneralSecurityException
+     * @throws IOException
+     */
+    public static void addCertificate(File keystoreFile, char[] storePass, String alias, Certificate cert)
+            throws GeneralSecurityException, IOException {
+        KeyStore keystore = getKeyStore(keystoreFile, storePass);
+
+        // Add the certificate
+        keystore.setCertificateEntry(alias, cert);
+
+        // Save the new keystore contents
+        FileOutputStream out = null;
+        try {
+            out = new FileOutputStream(keystoreFile);
+            keystore.store(out, storePass);
+        } finally {
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException ioe) {
+                    // Ignore
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/NamespaceContext.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/NamespaceContext.java
new file mode 100755
index 0000000..4928e64
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/NamespaceContext.java
@@ -0,0 +1,96 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.util;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Helper class in process of parsing signature out of SAML token.
+ * usage example:
+ * <code>
+ * xpath.setNamespaceContext(
+ * NamespaceContext.create()
+ * .addNsUriPair(xmlSignatureNSPrefix, JBossSAMLURIConstants.XMLDSIG_NSURI.get())
+ * );
+ * </code>
+ *
+ * @author Peter Skopek: pskopek at redhat dot com
+ */
+
+public class NamespaceContext implements javax.xml.namespace.NamespaceContext {
+
+    private Map<String, String> nsMap = new HashMap<String, String>();
+
+    public NamespaceContext() {
+    }
+
+    public NamespaceContext(String prefix, String uri) {
+        nsMap.put(prefix, uri);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * javax.xml.namespace.NamespaceContext#getNamespaceURI(java.lang.String)
+     */
+    public String getNamespaceURI(String prefix) {
+        return nsMap.get(prefix);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.xml.namespace.NamespaceContext#getPrefix(java.lang.String)
+     */
+    public String getPrefix(String namespaceURI) {
+        for (String key : nsMap.keySet()) {
+            String value = nsMap.get(key);
+            if (value.equals(namespaceURI)) {
+                return key;
+            }
+        }
+        return null;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.xml.namespace.NamespaceContext#getPrefixes(java.lang.String)
+     */
+    public Iterator<String> getPrefixes(String namespaceURI) {
+        return nsMap.keySet().iterator();
+    }
+
+    public NamespaceContext addNsUriPair(String ns, String uri) {
+        nsMap.put(ns, uri);
+        return this;
+    }
+
+    /**
+     * Create new NamespaceContext for use.
+     *
+     * @return
+     */
+    public static NamespaceContext create() {
+        return new NamespaceContext();
+    }
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/ProvidersUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/ProvidersUtil.java
new file mode 100755
index 0000000..cf6ec6f
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/ProvidersUtil.java
@@ -0,0 +1,127 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.util;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Provider;
+import java.security.Security;
+
+/**
+ * Utility dealing with the Santuario (XMLSec) providers registration for PicketLink
+ *
+ * @author alessio.soldano@jboss.com
+ * @since 07-May-2012
+ */
+public class ProvidersUtil {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * No-op call such that the default system properties are set
+     */
+    public static synchronized void ensure() {
+        AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+            public Boolean run() {
+                // register Apache Santuario 1.5.x XMLDSig version
+                addXMLDSigRI();
+                // register BC provider if available (to have additional encryption algorithms, etc.)
+                addJceProvider("BC", "org.bouncycastle.jce.provider.BouncyCastleProvider");
+                return true;
+            }
+        });
+    }
+
+    private static void addXMLDSigRI() {
+        try {
+            Class<?> clazz = SecurityActions
+                    .loadClass(XMLSignatureUtil.class, "org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI");
+            if (clazz == null)
+                throw logger.classNotLoadedError("org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI");
+            addJceProvider("ApacheXMLDSig", (Provider) clazz.newInstance());
+        } catch (Throwable t) {
+            // ignore - may be a NoClassDefFound if XMLDSigRI isn't avail
+            return;
+        }
+    }
+
+    /**
+     * Add a new JCE security provider to use for PicketLink.
+     *
+     * @param name The name string of the provider (this may not be the real name of the provider)
+     * @param provider A subclass of <code>java.security.Provider</code>
+     *
+     * @return Returns the actual name of the provider that was loaded
+     */
+    private static String addJceProvider(String name, Provider provider) {
+        Provider currentProvider = Security.getProvider(name);
+        if (currentProvider == null) {
+            try {
+                //
+                // Install the provider after the SUN provider (see WSS-99)
+                // Otherwise fall back to the old behaviour of inserting
+                // the provider in position 2. For AIX, install it after
+                // the IBMJCE provider.
+                //
+                int ret = 0;
+                Provider[] provs = Security.getProviders();
+                for (int i = 0; i < provs.length; i++) {
+                    if ("SUN".equals(provs[i].getName()) || "IBMJCE".equals(provs[i].getName())) {
+                        ret = Security.insertProviderAt(provider, i + 2);
+                        break;
+                    }
+                }
+                if (ret == 0) {
+                    ret = Security.insertProviderAt(provider, 2);
+                }
+                if (logger.isDebugEnabled()) {
+                    logger.debug("The provider " + provider.getName() + " - " + provider.getVersion() + " was added at position: "
+                            + ret);
+                }
+                return provider.getName();
+            } catch (Throwable t) {
+                if (logger.isDebugEnabled()) {
+                    logger.jceProviderCouldNotBeLoaded(name, t);
+                }
+                return null;
+            }
+        }
+        return currentProvider.getName();
+    }
+
+    private static String addJceProvider(String name, String className) {
+        Provider currentProvider = Security.getProvider(name);
+        if (currentProvider == null) {
+            try {
+                // Class<? extends Provider> clazz = Loader.loadClass(className, false, Provider.class);
+                Class<? extends Provider> clazz = Class.forName(className).asSubclass(Provider.class);
+                Provider provider = clazz.newInstance();
+                return addJceProvider(name, provider);
+            } catch (Throwable t) {
+                if (logger.isDebugEnabled()) {
+                    logger.jceProviderCouldNotBeLoaded(name, t);
+                }
+                return null;
+            }
+        }
+        return currentProvider.getName();
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SchemaManagerUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SchemaManagerUtil.java
new file mode 100755
index 0000000..758133d
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SchemaManagerUtil.java
@@ -0,0 +1,106 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Manages the schemas for PicketLink
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jun 30, 2011
+ */
+public class SchemaManagerUtil {
+
+    public static List<String> getXMLSchemas() {
+        List<String> list = new ArrayList<String>();
+
+        list.add("schema/w3c/xmlschema/xml.xsd");
+        return list;
+    }
+
+    public static List<String> getXMLDSig() {
+        List<String> list = new ArrayList<String>();
+
+        list.add("schema/w3c/xmldsig/xmldsig-core-schema.xsd");
+        return list;
+    }
+
+    public static List<String> getXMLEnc() {
+        List<String> list = new ArrayList<String>();
+
+        list.add("schema/w3c/xmlenc/xenc-schema.xsd");
+        return list;
+    }
+
+    public static List<String> getXACMLSchemas() {
+        List<String> list = new ArrayList<String>();
+
+        list.add("schema/access_control-xacml-2.0-policy-schema-os.xsd");
+        list.add("schema/access_control-xacml-2.0-context-schema-os.xsd");
+        return list;
+    }
+
+    public static List<String> getSAML2Schemas() {
+        List<String> list = new ArrayList<String>();
+
+        list.add("schema/saml/v2/saml-schema-assertion-2.0.xsd");
+        list.add("schema/saml/v2/saml-schema-protocol-2.0.xsd");
+        list.add("schema/saml/v2/saml-schema-metadata-2.0.xsd");
+        list.add("schema/saml/v2/saml-schema-x500-2.0.xsd");
+        list.add("schema/saml/v2/saml-schema-authn-context-2.0.xsd");
+        list.add("schema/saml/v2/saml-schema-authn-context-types-2.0.xsd");
+        list.add("schema/saml/v2/saml-schema-xacml-2.0.xsd");
+        list.add("schema/saml/v2/access_control-xacml-2.0-saml-assertion-schema-os.xsd");
+        list.add("schema/saml/v2/access_control-xacml-2.0-saml-protocol-schema-os.xsd");
+        return list;
+    }
+
+    public static List<String> getSAML11Schemas() {
+        List<String> list = new ArrayList<String>();
+
+        list.add("schema/saml/v1/saml-schema-assertion-1.0.xsd");
+        list.add("schema/saml/v1/oasis-sstc-saml-schema-assertion-1.1.xsd");
+        list.add("schema/saml/v1/saml-schema-protocol-1.1.xsd");
+        return list;
+    }
+
+    public static List<String> getWSTrustSchemas() {
+        List<String> list = new ArrayList<String>();
+
+        list.add("schema/wstrust/v1_3/ws-trust-1.3.xsd");
+        list.add("schema/wstrust/v1_3/oasis-200401-wss-wssecurity-secext-1.0.xsd");
+        list.add("schema/wstrust/v1_3/oasis-200401-wss-wssecurity-utility-1.0.xsd");
+        list.add("schema/wstrust/v1_3/ws-policy.xsd");
+        list.add("schema/wstrust/v1_3/ws-addr.xsd");
+        return list;
+    }
+
+    public static List<String> getSchemas() {
+        List<String> list = new ArrayList<String>();
+        list.addAll(getXMLSchemas());
+        list.addAll(getXMLDSig());
+        list.addAll(getXMLEnc());
+        list.addAll(getSAML2Schemas());
+        list.addAll(getSAML11Schemas());
+        list.addAll(getXACMLSchemas());
+        list.addAll(getWSTrustSchemas());
+        return list;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SecurityActions.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SecurityActions.java
new file mode 100755
index 0000000..d7c5382
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SecurityActions.java
@@ -0,0 +1,225 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.util;
+
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 9, 2008
+ */
+class SecurityActions {
+
+    /**
+     * <p>
+     * Loads a {@link Class} using the <code>fullQualifiedName</code> supplied. This method tries first to load from
+     * the
+     * specified {@link Class}, if not found it will try to load from using TCL.
+     * </p>
+     *
+     * @param theClass
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final Class<?> theClass, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    ClassLoader classLoader = theClass.getClassLoader();
+
+                    Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+                    if (clazz == null) {
+                        classLoader = Thread.currentThread().getContextClassLoader();
+                        clazz = loadClass(classLoader, fullQualifiedName);
+                    }
+                    return clazz;
+                }
+            });
+        } else {
+            ClassLoader classLoader = theClass.getClassLoader();
+
+            Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+            if (clazz == null) {
+                classLoader = Thread.currentThread().getContextClassLoader();
+                clazz = loadClass(classLoader, fullQualifiedName);
+            }
+            return clazz;
+        }
+    }
+
+    /**
+     * <p>
+     * Loads a class from the specified {@link ClassLoader} using the <code>fullQualifiedName</code> supplied.
+     * </p>
+     *
+     * @param classLoader
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final ClassLoader classLoader, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    try {
+                        return classLoader.loadClass(fullQualifiedName);
+                    } catch (ClassNotFoundException e) {
+                    }
+                    return null;
+                }
+            });
+        } else {
+            try {
+                return classLoader.loadClass(fullQualifiedName);
+            } catch (ClassNotFoundException e) {
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Load a resource based on the passed {@link Class} classloader. Failing which try with the Thread Context CL
+     *
+     * @param clazz
+     * @param resourceName
+     *
+     * @return
+     */
+    static URL loadResource(final Class<?> clazz, final String resourceName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<URL>() {
+                public URL run() {
+                    URL url = null;
+                    ClassLoader clazzLoader = clazz.getClassLoader();
+                    url = clazzLoader.getResource(resourceName);
+
+                    if (url == null) {
+                        clazzLoader = Thread.currentThread().getContextClassLoader();
+                        url = clazzLoader.getResource(resourceName);
+                    }
+
+                    return url;
+                }
+            });
+        } else {
+            URL url = null;
+            ClassLoader clazzLoader = clazz.getClassLoader();
+            url = clazzLoader.getResource(resourceName);
+
+            if (url == null) {
+                clazzLoader = Thread.currentThread().getContextClassLoader();
+                url = clazzLoader.getResource(resourceName);
+            }
+
+            return url;
+        }
+    }
+
+    /**
+     * Set the system property
+     *
+     * @param key
+     * @param defaultValue
+     *
+     * @return
+     */
+    static void setSystemProperty(final String key, final String value) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                public Object run() {
+                    System.setProperty(key, value);
+                    return null;
+                }
+            });
+        } else {
+            System.setProperty(key, value);
+        }
+    }
+
+    /**
+     * <p>Returns a system property value using the specified <code>key</code>. If not found the
+     * <code>defaultValue</code> will be returned.</p>
+     *
+     * @param key
+     * @param defaultValue
+     *
+     * @return
+     */
+    static String getSystemProperty(final String key, final String defaultValue) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty(key, defaultValue);
+                }
+            });
+        } else {
+            return System.getProperty(key, defaultValue);
+        }
+    }
+
+    /**
+     * Get the Thread Context ClassLoader
+     *
+     * @return
+     */
+    static ClassLoader getTCCL() {
+        if (System.getSecurityManager() != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
+                    return Thread.currentThread().getContextClassLoader();
+                }
+            });
+        } else {
+            return Thread.currentThread().getContextClassLoader();
+        }
+    }
+
+    /**
+     * Set the Thread Context ClassLoader
+     *
+     * @param paramCl
+     */
+    static void setTCCL(final ClassLoader paramCl) {
+        if (System.getSecurityManager() != null) {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    Thread.currentThread().setContextClassLoader(paramCl);
+                    return null;
+                }
+            });
+        } else {
+
+            Thread.currentThread().setContextClassLoader(paramCl);
+        }
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SignatureUtilTransferObject.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SignatureUtilTransferObject.java
new file mode 100755
index 0000000..96e3f69
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SignatureUtilTransferObject.java
@@ -0,0 +1,115 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.core.util;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import java.security.KeyPair;
+import java.security.cert.X509Certificate;
+
+/**
+ * A Transfer Object used by {@link XMLSignatureUtil}
+ *
+ * @author anil saldhana
+ */
+public class SignatureUtilTransferObject {
+
+    private X509Certificate x509Certificate;
+
+    private Document documentToBeSigned;
+    private KeyPair keyPair;
+
+    private Node nextSibling;
+
+    private String digestMethod;
+
+    private String referenceURI;
+
+    private String signatureMethod;
+
+    public Document getDocumentToBeSigned() {
+        return documentToBeSigned;
+    }
+
+    public void setDocumentToBeSigned(Document documentToBeSigned) {
+        this.documentToBeSigned = documentToBeSigned;
+    }
+
+    public KeyPair getKeyPair() {
+        return keyPair;
+    }
+
+    public void setKeyPair(KeyPair keyPair) {
+        this.keyPair = keyPair;
+    }
+
+    public Node getNextSibling() {
+        return nextSibling;
+    }
+
+    public void setNextSibling(Node nextSibling) {
+        this.nextSibling = nextSibling;
+    }
+
+    public String getDigestMethod() {
+        return digestMethod;
+    }
+
+    public void setDigestMethod(String digestMethod) {
+        this.digestMethod = digestMethod;
+    }
+
+    public String getReferenceURI() {
+        return referenceURI;
+    }
+
+    public void setReferenceURI(String referenceURI) {
+        this.referenceURI = referenceURI;
+    }
+
+    public String getSignatureMethod() {
+        return signatureMethod;
+    }
+
+    public void setSignatureMethod(String signatureMethod) {
+        this.signatureMethod = signatureMethod;
+    }
+
+    /**
+     * Get the {@link X509Certificate} used for signing
+     *
+     * @return
+     *
+     * @since 2.5.0
+     */
+    public X509Certificate getX509Certificate() {
+        return x509Certificate;
+    }
+
+    /**
+     * Set the {@link X509Certificate} used for signing
+     *
+     * @param x509Certificate
+     *
+     * @since 2.5.0
+     */
+    public void setX509Certificate(X509Certificate x509Certificate) {
+        this.x509Certificate = x509Certificate;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/PostBindingUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/PostBindingUtil.java
new file mode 100755
index 0000000..3cf658a
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/PostBindingUtil.java
@@ -0,0 +1,94 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.keycloak.saml.processing.web.util;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.util.Base64;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Utility for the HTTP/Post binding
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since May 22, 2009
+ */
+public class PostBindingUtil {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * Apply base64 encoding on the message
+     *
+     * @param stringToEncode
+     *
+     * @return
+     */
+    public static String base64Encode(String stringToEncode) throws IOException {
+        return Base64.encodeBytes(stringToEncode.getBytes("UTF-8"), Base64.DONT_BREAK_LINES);
+    }
+
+    /**
+     * Apply base64 decoding on the message and return the byte array
+     *
+     * @param encodedString
+     *
+     * @return
+     */
+    public static byte[] base64Decode(String encodedString) {
+        if (encodedString == null)
+            throw logger.nullArgumentError("encodedString");
+
+        return Base64.decode(encodedString);
+    }
+
+    /**
+     * Apply base64 decoding on the message and return the stream
+     *
+     * @param encodedString
+     *
+     * @return
+     */
+    public static InputStream base64DecodeAsStream(String encodedString) {
+        if (encodedString == null)
+            throw logger.nullArgumentError("encodedString");
+
+        return new ByteArrayInputStream(base64Decode(encodedString));
+    }
+
+    public static String escapeHTML(String toEscape) {
+        StringBuilder escaped = new StringBuilder();
+
+        for (int i = 0; i < toEscape.length(); i++) {
+            char chr = toEscape.charAt(i);
+
+            if (chr != '"' && chr != '<' && chr != '>') {
+                escaped.append(chr);
+            }
+        }
+
+        return escaped.toString();
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingSignatureUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingSignatureUtil.java
new file mode 100755
index 0000000..a9c3765
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingSignatureUtil.java
@@ -0,0 +1,345 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.web.util;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.util.DocumentUtil;
+import org.keycloak.saml.processing.api.saml.v2.request.SAML2Request;
+import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
+import org.keycloak.saml.processing.core.saml.v2.util.SignatureUtil;
+import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.security.GeneralSecurityException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+import static org.keycloak.saml.common.util.StringUtil.isNotNull;
+
+/**
+ * Signature Support for the HTTP/Redirect binding
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 16, 2008
+ */
+public class RedirectBindingSignatureUtil {
+
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    /**
+     * Get the URL for the SAML request that contains the signature and signature algorithm
+     *
+     * @param authRequest
+     * @param relayState
+     * @param signingKey
+     *
+     * @return
+     *
+     * @throws SAXException
+     * @throws IOException
+     * @throws GeneralSecurityException
+     */
+    public static String getSAMLRequestURLWithSignature(AuthnRequestType authRequest, String relayState, PrivateKey signingKey)
+            throws SAXException, IOException, GeneralSecurityException {
+        SAML2Request saml2Request = new SAML2Request();
+
+        // Deal with the original request
+        StringWriter sw = new StringWriter();
+
+        saml2Request.marshall(authRequest, sw);
+
+        // URL Encode the Request
+        String urlEncodedRequest = RedirectBindingUtil.deflateBase64URLEncode(sw.toString());
+
+        String urlEncodedRelayState = null;
+
+        if (isNotNull(relayState))
+            urlEncodedRelayState = URLEncoder.encode(relayState, "UTF-8");
+
+        byte[] sigValue = computeSignature(GeneralConstants.SAML_REQUEST_KEY, urlEncodedRequest, urlEncodedRelayState,
+                signingKey);
+
+        // Now construct the URL
+        return getRequestRedirectURLWithSignature(urlEncodedRequest, urlEncodedRelayState, sigValue, signingKey.getAlgorithm());
+    }
+
+    /**
+     * Get the URL for the SAML request that contains the signature and signature algorithm
+     *
+     * @param responseType
+     * @param relayState
+     * @param signingKey
+     *
+     * @return
+     *
+     * @throws IOException
+     * @throws GeneralSecurityException
+     */
+    public static String getSAMLResponseURLWithSignature(ResponseType responseType, String relayState, PrivateKey signingKey)
+            throws IOException, GeneralSecurityException {
+        SAML2Response saml2Response = new SAML2Response();
+
+        Document responseDoc = saml2Response.convert(responseType);
+
+        // URL Encode the Request
+        String responseString = DocumentUtil.getDocumentAsString(responseDoc);
+
+        String urlEncodedResponse = RedirectBindingUtil.deflateBase64URLEncode(responseString);
+
+        String urlEncodedRelayState = null;
+        if (isNotNull(relayState))
+            urlEncodedRelayState = URLEncoder.encode(relayState, "UTF-8");
+
+        byte[] sigValue = computeSignature(GeneralConstants.SAML_RESPONSE_KEY, urlEncodedResponse, urlEncodedRelayState,
+                signingKey);
+
+        // Now construct the URL
+        return getResponseRedirectURLWithSignature(urlEncodedResponse, urlEncodedRelayState, sigValue,
+                signingKey.getAlgorithm());
+    }
+
+    /**
+     * Given an url-encoded saml request and relay state and a private key, compute the url
+     *
+     * @param urlEncodedRequest
+     * @param urlEncodedRelayState
+     * @param signingKey
+     *
+     * @return
+     *
+     * @throws GeneralSecurityException
+     * @throws IOException
+     */
+    public static String getSAMLRequestURLWithSignature(String urlEncodedRequest, String urlEncodedRelayState,
+                                                        PrivateKey signingKey) throws IOException, GeneralSecurityException {
+        byte[] sigValue = computeSignature(GeneralConstants.SAML_REQUEST_KEY, urlEncodedRequest, urlEncodedRelayState,
+                signingKey);
+        return getRequestRedirectURLWithSignature(urlEncodedRequest, urlEncodedRelayState, sigValue, signingKey.getAlgorithm());
+    }
+
+    /**
+     * Given an url-encoded saml response and relay state and a private key, compute the url
+     *
+     * @param urlEncodedResponse
+     * @param urlEncodedRelayState
+     * @param signingKey
+     *
+     * @return
+     *
+     * @throws GeneralSecurityException
+     * @throws IOException
+     */
+    public static String getSAMLResponseURLWithSignature(String urlEncodedResponse, String urlEncodedRelayState,
+                                                         PrivateKey signingKey) throws IOException, GeneralSecurityException {
+        byte[] sigValue = computeSignature(GeneralConstants.SAML_RESPONSE_KEY, urlEncodedResponse, urlEncodedRelayState,
+                signingKey);
+        return getResponseRedirectURLWithSignature(urlEncodedResponse, urlEncodedRelayState, sigValue,
+                signingKey.getAlgorithm());
+    }
+
+    /**
+     * From the SAML Request URL, get the Request object
+     *
+     * @param signedURL
+     *
+     * @return
+     *
+     * @throws IOException
+     * @throws ParsingException
+     * @throws org.keycloak.saml.common.exceptions.ProcessingException
+     * @throws ConfigurationException
+     */
+    public static AuthnRequestType getRequestFromSignedURL(String signedURL) throws ConfigurationException,
+            ProcessingException, ParsingException, IOException {
+        String samlRequestTokenValue = getTokenValue(signedURL, GeneralConstants.SAML_REQUEST_KEY);
+
+        SAML2Request saml2Request = new SAML2Request();
+        return saml2Request.getAuthnRequestType(RedirectBindingUtil.urlBase64DeflateDecode(samlRequestTokenValue));
+    }
+
+    /**
+     * Get the signature value from the url
+     *
+     * @param signedURL
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public static byte[] getSignatureValueFromSignedURL(String signedURL) throws IOException {
+        String sigValueTokenValue = getTokenValue(signedURL, GeneralConstants.SAML_SIGNATURE_REQUEST_KEY);
+        if (sigValueTokenValue == null)
+            throw new IllegalStateException(logger.samlHandlerSignatureNotPresentError());
+        return RedirectBindingUtil.urlBase64Decode(sigValueTokenValue);
+    }
+
+    /**
+     * From the query string that contains key/value pairs, get the value of a key <b>Note:</b> if the token is null, a
+     * null
+     * value is returned
+     *
+     * @param queryString
+     * @param token
+     *
+     * @return
+     */
+    public static String getTokenValue(String queryString, String token) {
+        return getTokenValue(getToken(queryString, token));
+    }
+
+    public static boolean validateSignature(String queryString, PublicKey validatingKey, byte[] sigValue)
+            throws UnsupportedEncodingException, GeneralSecurityException {
+        // Construct the url again
+        StringBuilder sb = new StringBuilder();
+
+        if (isRequestQueryString(queryString)) {
+            addParameter(sb, GeneralConstants.SAML_REQUEST_KEY,
+                    RedirectBindingSignatureUtil.getTokenValue(queryString, GeneralConstants.SAML_REQUEST_KEY));
+        } else {
+            addParameter(sb, GeneralConstants.SAML_RESPONSE_KEY,
+                    RedirectBindingSignatureUtil.getTokenValue(queryString, GeneralConstants.SAML_RESPONSE_KEY));
+        }
+
+        String relayStateFromURL = RedirectBindingSignatureUtil.getTokenValue(queryString, GeneralConstants.RELAY_STATE);
+
+        if (isNotNull(relayStateFromURL)) {
+            addParameter(sb, GeneralConstants.RELAY_STATE, relayStateFromURL);
+        }
+
+        addParameter(sb, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY,
+                RedirectBindingSignatureUtil.getTokenValue(queryString, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY));
+
+        return SignatureUtil.validate(sb.toString().getBytes("UTF-8"), sigValue, validatingKey);
+    }
+
+    private static boolean isRequestQueryString(String queryString) {
+        return RedirectBindingSignatureUtil.getTokenValue(queryString, GeneralConstants.SAML_REQUEST_KEY) != null;
+    }
+
+    // ***************** Private Methods **************
+
+    private static byte[] computeSignature(String samlParameter, String urlEncoded, String urlEncodedRelayState,
+                                           PrivateKey signingKey) throws IOException, GeneralSecurityException {
+        StringBuilder sb = new StringBuilder();
+
+        addParameter(sb, samlParameter, urlEncoded);
+
+        if (isNotNull(urlEncodedRelayState)) {
+            addParameter(sb, GeneralConstants.RELAY_STATE, urlEncodedRelayState);
+        }
+
+        // SigAlg
+        String algo = signingKey.getAlgorithm();
+        String sigAlg = SignatureUtil.getXMLSignatureAlgorithmURI(algo);
+
+        sigAlg = URLEncoder.encode(sigAlg, "UTF-8");
+
+        addParameter(sb, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, sigAlg);
+
+        byte[] sigValue = SignatureUtil.sign(sb.toString(), signingKey);
+
+        return sigValue;
+    }
+
+    private static String getRequestRedirectURLWithSignature(String urlEncodedRequest, String urlEncodedRelayState,
+                                                             byte[] signature, String sigAlgo) throws IOException {
+        return getRedirectURLWithSignature(GeneralConstants.SAML_REQUEST_KEY, urlEncodedRequest, urlEncodedRelayState,
+                signature, sigAlgo);
+    }
+
+    private static String getResponseRedirectURLWithSignature(String urlEncodedResponse, String urlEncodedRelayState,
+                                                              byte[] signature, String sigAlgo) throws IOException {
+        return getRedirectURLWithSignature(GeneralConstants.SAML_RESPONSE_KEY, urlEncodedResponse, urlEncodedRelayState,
+                signature, sigAlgo);
+    }
+
+    private static String getRedirectURLWithSignature(String samlParameter, String urlEncoded, String urlEncodedRelayState,
+                                                      byte[] signature, String sigAlgo) throws IOException {
+        StringBuilder sb = new StringBuilder();
+
+        addParameter(sb, samlParameter, urlEncoded);
+
+        if (isNotNull(urlEncodedRelayState)) {
+            addParameter(sb, GeneralConstants.RELAY_STATE, urlEncodedRelayState);
+        }
+
+        // SigAlg
+        String sigAlg = SignatureUtil.getXMLSignatureAlgorithmURI(sigAlgo);
+
+        sigAlg = URLEncoder.encode(sigAlg, "UTF-8");
+
+        addParameter(sb, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, sigAlg);
+
+        // Encode the signature value
+        String encodedSig = RedirectBindingUtil.base64URLEncode(signature);
+
+        addParameter(sb, GeneralConstants.SAML_SIGNATURE_REQUEST_KEY, encodedSig);
+
+        return sb.toString();
+    }
+
+    private static void addParameter(StringBuilder queryString, String paramName, String paramValue) {
+        String parameterSeparator = "&";
+
+        if (queryString.length() == 0) {
+            parameterSeparator = "";
+        }
+
+        queryString.append(parameterSeparator).append(paramName).append("=").append(paramValue);
+    }
+
+    private static String getToken(String queryString, String token) {
+        if (queryString == null)
+            throw logger.nullArgumentError("queryString");
+
+        token += "=";
+
+        int start = queryString.indexOf(token);
+        if (start < 0)
+            return null;
+
+        int end = queryString.indexOf("&", start);
+
+        if (end == -1)
+            return queryString.substring(start);
+
+        return queryString.substring(start, end);
+    }
+
+    private static String getTokenValue(String token) {
+        if (token == null)
+            return token;
+
+        int eq = token.indexOf('=');
+        if (eq == -1)
+            return token;
+        else
+            return token.substring(eq + 1);
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingUtil.java
new file mode 100755
index 0000000..0e1c7f7
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingUtil.java
@@ -0,0 +1,219 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.web.util;
+
+import org.keycloak.saml.common.util.Base64;
+import org.keycloak.saml.processing.api.util.DeflateUtil;
+import org.keycloak.saml.common.util.StringUtil;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+
+/**
+ * Utility class for SAML HTTP/Redirect binding
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Jan 14, 2009
+ */
+public class RedirectBindingUtil {
+
+    /**
+     * URL encode the string
+     *
+     * @param str
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public static String urlEncode(String str) throws IOException {
+        return URLEncoder.encode(str, "UTF-8");
+    }
+
+    /**
+     * URL decode the string
+     *
+     * @param str
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public static String urlDecode(String str) throws IOException {
+        return URLDecoder.decode(str, "UTF-8");
+    }
+
+    /**
+     * On the byte array, apply base64 encoding following by URL encoding
+     *
+     * @param stringToEncode
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public static String base64URLEncode(byte[] stringToEncode) throws IOException {
+        String base64Request = Base64.encodeBytes(stringToEncode, Base64.DONT_BREAK_LINES);
+        return urlEncode(base64Request);
+    }
+
+    /**
+     * On the byte array, apply URL decoding followed by base64 decoding
+     *
+     * @param encodedString
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public static byte[] urlBase64Decode(String encodedString) throws IOException {
+        String decodedString = urlDecode(encodedString);
+        return Base64.decode(decodedString);
+    }
+
+    /**
+     * Apply deflate compression followed by base64 encoding and URL encoding
+     *
+     * @param stringToEncode
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public static String deflateBase64URLEncode(String stringToEncode) throws IOException {
+        return deflateBase64URLEncode(stringToEncode.getBytes("UTF-8"));
+    }
+
+    /**
+     * Apply deflate compression followed by base64 encoding and URL encoding
+     *
+     * @param stringToEncode
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public static String deflateBase64URLEncode(byte[] stringToEncode) throws IOException {
+        byte[] deflatedMsg = DeflateUtil.encode(stringToEncode);
+        return base64URLEncode(deflatedMsg);
+    }
+
+    /**
+     * Apply deflate compression followed by base64 encoding
+     *
+     * @param stringToEncode
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public static String deflateBase64Encode(byte[] stringToEncode) throws IOException {
+        byte[] deflatedMsg = DeflateUtil.encode(stringToEncode);
+        return Base64.encodeBytes(deflatedMsg);
+    }
+
+    /**
+     * Apply URL decoding, followed by base64 decoding followed by deflate decompression
+     *
+     * @param encodedString
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public static InputStream urlBase64DeflateDecode(String encodedString) throws IOException {
+        byte[] deflatedString = urlBase64Decode(encodedString);
+        return DeflateUtil.decode(deflatedString);
+    }
+
+    /**
+     * Base64 decode followed by Deflate decoding
+     *
+     * @param encodedString
+     *
+     * @return
+     */
+    public static InputStream base64DeflateDecode(String encodedString) {
+        byte[] base64decodedMsg = Base64.decode(encodedString);
+        return DeflateUtil.decode(base64decodedMsg);
+    }
+
+    /**
+     * Get the Query String for the destination url
+     *
+     * @param urlEncodedRequest
+     * @param urlEncodedRelayState
+     * @param sendRequest either going to be saml request or response
+     *
+     * @return
+     */
+    public static String getDestinationQueryString(String urlEncodedRequest, String urlEncodedRelayState, boolean sendRequest) {
+        StringBuilder sb = new StringBuilder();
+        if (sendRequest)
+            sb.append("SAMLRequest=").append(urlEncodedRequest);
+        else
+            sb.append("SAMLResponse=").append(urlEncodedRequest);
+        if (StringUtil.isNotNull(urlEncodedRelayState))
+            sb.append("&RelayState=").append(urlEncodedRelayState);
+        return sb.toString();
+    }
+
+    /**
+     * Get the destination url
+     *
+     * @param holder
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public static String getDestinationURL(RedirectBindingUtilDestHolder holder) throws IOException {
+        String destination = holder.destination;
+        StringBuilder destinationURL = new StringBuilder(destination);
+
+        if (destination.contains("?"))
+            destinationURL.append("&");
+        else
+            destinationURL.append("?");
+
+        destinationURL.append(holder.destinationQueryString);
+
+        return destinationURL.toString();
+    }
+
+    /**
+     * A Destination holder that holds the destination host url and the destination query string
+     */
+    public static class RedirectBindingUtilDestHolder {
+
+        private String destination;
+        private String destinationQueryString;
+
+        public RedirectBindingUtilDestHolder setDestinationQueryString(String dest) {
+            destinationQueryString = dest;
+            return this;
+        }
+
+        public RedirectBindingUtilDestHolder setDestination(String dest) {
+            destination = dest;
+            return this;
+        }
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/SecurityActions.java b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/SecurityActions.java
new file mode 100755
index 0000000..a5411c9
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/SecurityActions.java
@@ -0,0 +1,125 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml.processing.web.util;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ *
+ * @author Anil.Saldhana@redhat.com
+ * @since Dec 9, 2008
+ */
+class SecurityActions {
+
+    /**
+     * <p>
+     * Loads a {@link Class} using the <code>fullQualifiedName</code> supplied. This method tries first to load from
+     * the
+     * specified {@link Class}, if not found it will try to load from using TCL.
+     * </p>
+     *
+     * @param theClass
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final Class<?> theClass, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    ClassLoader classLoader = theClass.getClassLoader();
+
+                    Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+                    if (clazz == null) {
+                        classLoader = Thread.currentThread().getContextClassLoader();
+                        clazz = loadClass(classLoader, fullQualifiedName);
+                    }
+                    return clazz;
+                }
+            });
+        } else {
+            ClassLoader classLoader = theClass.getClassLoader();
+
+            Class<?> clazz = loadClass(classLoader, fullQualifiedName);
+            if (clazz == null) {
+                classLoader = Thread.currentThread().getContextClassLoader();
+                clazz = loadClass(classLoader, fullQualifiedName);
+            }
+            return clazz;
+        }
+    }
+
+    /**
+     * <p>
+     * Loads a class from the specified {@link ClassLoader} using the <code>fullQualifiedName</code> supplied.
+     * </p>
+     *
+     * @param classLoader
+     * @param fullQualifiedName
+     *
+     * @return
+     */
+    static Class<?> loadClass(final ClassLoader classLoader, final String fullQualifiedName) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    try {
+                        return classLoader.loadClass(fullQualifiedName);
+                    } catch (ClassNotFoundException e) {
+                    }
+                    return null;
+                }
+            });
+        } else {
+            try {
+                return classLoader.loadClass(fullQualifiedName);
+            } catch (ClassNotFoundException e) {
+            }
+            return null;
+        }
+    }
+
+    /**
+     * <p>Returns a system property value using the specified <code>key</code>. If not found the
+     * <code>defaultValue</code> will be returned.</p>
+     *
+     * @param key
+     * @param defaultValue
+     *
+     * @return
+     */
+    static String getSystemProperty(final String key, final String defaultValue) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty(key, defaultValue);
+                }
+            });
+        } else {
+            return System.getProperty(key, defaultValue);
+        }
+    }
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/RandomSecret.java b/saml-core/src/main/java/org/keycloak/saml/RandomSecret.java
new file mode 100755
index 0000000..67f4ba7
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/RandomSecret.java
@@ -0,0 +1,25 @@
+package org.keycloak.saml;
+
+import java.security.SecureRandom;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class RandomSecret {
+    /**
+     * <p>
+     * Creates a random {@code byte[]} secret of the specified size.
+     * </p>
+     *
+     * @param size the size of the secret to be created, in bytes.
+     *
+     * @return a {@code byte[]} containing the generated secret.
+     */
+    public static byte[] createRandomSecret(final int size) {
+        SecureRandom random = new SecureRandom();
+        byte[] secret = new byte[size];
+        random.nextBytes(secret);
+        return secret;
+    }
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/SAML2AuthnRequestBuilder.java b/saml-core/src/main/java/org/keycloak/saml/SAML2AuthnRequestBuilder.java
new file mode 100755
index 0000000..b043a12
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/SAML2AuthnRequestBuilder.java
@@ -0,0 +1,99 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml;
+
+import java.net.URI;
+
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.processing.api.saml.v2.request.SAML2Request;
+import org.keycloak.saml.processing.core.saml.v2.common.IDGenerator;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.w3c.dom.Document;
+
+/**
+ * @author pedroigor
+ */
+public class SAML2AuthnRequestBuilder {
+
+    private final AuthnRequestType authnRequestType;
+    protected String destination;
+    protected String issuer;
+
+    public SAML2AuthnRequestBuilder destination(String destination) {
+        this.destination = destination;
+        return this;
+    }
+
+    public SAML2AuthnRequestBuilder issuer(String issuer) {
+        this.issuer = issuer;
+        return this;
+    }
+
+    public SAML2AuthnRequestBuilder() {
+        try {
+            this.authnRequestType = new AuthnRequestType(IDGenerator.create("ID_"), XMLTimeUtil.getIssueInstant());
+        } catch (ConfigurationException e) {
+            throw new RuntimeException("Could not create SAML AuthnRequest builder.", e);
+        }
+    }
+
+    public SAML2AuthnRequestBuilder assertionConsumerUrl(String assertionConsumerUrl) {
+        this.authnRequestType.setAssertionConsumerServiceURL(URI.create(assertionConsumerUrl));
+        return this;
+    }
+
+    public SAML2AuthnRequestBuilder forceAuthn(boolean forceAuthn) {
+        this.authnRequestType.setForceAuthn(forceAuthn);
+        return this;
+    }
+
+    public SAML2AuthnRequestBuilder isPassive(boolean isPassive) {
+        this.authnRequestType.setIsPassive(isPassive);
+        return this;
+    }
+
+    public SAML2AuthnRequestBuilder nameIdPolicy(SAML2NameIDPolicyBuilder nameIDPolicy) {
+        this.authnRequestType.setNameIDPolicy(nameIDPolicy.build());
+        return this;
+    }
+
+    public SAML2AuthnRequestBuilder protocolBinding(String protocolBinding) {
+        this.authnRequestType.setProtocolBinding(URI.create(protocolBinding));
+        return this;
+    }
+
+    public Document toDocument() {
+        try {
+            AuthnRequestType authnRequestType = this.authnRequestType;
+
+            NameIDType nameIDType = new NameIDType();
+
+            nameIDType.setValue(this.issuer);
+
+            authnRequestType.setIssuer(nameIDType);
+
+            authnRequestType.setDestination(URI.create(this.destination));
+
+            return new SAML2Request().convert(authnRequestType);
+        } catch (Exception e) {
+            throw new RuntimeException("Could not convert " + authnRequestType + " to a document.", e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/SAML2ErrorResponseBuilder.java b/saml-core/src/main/java/org/keycloak/saml/SAML2ErrorResponseBuilder.java
new file mode 100755
index 0000000..2373656
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/SAML2ErrorResponseBuilder.java
@@ -0,0 +1,72 @@
+package org.keycloak.saml;
+
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.protocol.StatusCodeType;
+import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+import org.keycloak.dom.saml.v2.protocol.StatusType;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
+import org.keycloak.saml.processing.core.saml.v2.common.IDGenerator;
+import org.keycloak.saml.processing.core.saml.v2.factories.JBossSAMLAuthnResponseFactory;
+import org.keycloak.saml.processing.core.saml.v2.holders.IDPInfoHolder;
+import org.keycloak.saml.processing.core.saml.v2.holders.IssuerInfoHolder;
+import org.keycloak.saml.processing.core.saml.v2.holders.SPInfoHolder;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.w3c.dom.Document;
+
+import java.net.URI;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class SAML2ErrorResponseBuilder {
+
+    protected String status;
+    protected String destination;
+    protected String issuer;
+
+    public SAML2ErrorResponseBuilder status(String status) {
+        this.status = status;
+        return this;
+    }
+
+    public SAML2ErrorResponseBuilder destination(String destination) {
+        this.destination = destination;
+        return this;
+    }
+
+    public SAML2ErrorResponseBuilder issuer(String issuer) {
+        this.issuer = issuer;
+        return this;
+    }
+
+
+    public Document buildDocument() throws ProcessingException {
+
+        try {
+            StatusResponseType statusResponse = new StatusResponseType(IDGenerator.create("ID_"), XMLTimeUtil.getIssueInstant());
+
+            statusResponse.setStatus(JBossSAMLAuthnResponseFactory.createStatusTypeForResponder(status));
+            NameIDType issuer = new NameIDType();
+            issuer.setValue(this.issuer);
+
+            statusResponse.setIssuer(issuer);
+            statusResponse.setDestination(destination);
+
+            SAML2Response saml2Response = new SAML2Response();
+            return saml2Response.convert(statusResponse);
+        } catch (ConfigurationException e) {
+            throw new ProcessingException(e);
+        } catch (ParsingException e) {
+            throw new ProcessingException(e);
+        }
+
+    }
+
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/SAML2LoginResponseBuilder.java b/saml-core/src/main/java/org/keycloak/saml/SAML2LoginResponseBuilder.java
new file mode 100755
index 0000000..9ca5f67
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/SAML2LoginResponseBuilder.java
@@ -0,0 +1,195 @@
+package org.keycloak.saml;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.util.DocumentUtil;
+import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
+import org.keycloak.saml.processing.core.saml.v2.common.IDGenerator;
+import org.keycloak.saml.processing.core.saml.v2.holders.IDPInfoHolder;
+import org.keycloak.saml.processing.core.saml.v2.holders.IssuerInfoHolder;
+import org.keycloak.saml.processing.core.saml.v2.holders.SPInfoHolder;
+import org.keycloak.saml.processing.core.saml.v2.util.StatementUtil;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
+import org.keycloak.dom.saml.v2.assertion.AuthnStatementType;
+import org.keycloak.dom.saml.v2.assertion.ConditionsType;
+import org.keycloak.dom.saml.v2.assertion.SubjectConfirmationDataType;
+import org.keycloak.dom.saml.v2.assertion.AudienceRestrictionType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.w3c.dom.Document;
+import java.net.URI;
+
+import static org.keycloak.saml.common.util.StringUtil.isNotNull;
+
+/**
+ * <p> Handles for dealing with SAML2 Authentication </p>
+ * <p/>
+ * Configuration Options:
+ *
+ * @author bburke@redhat.com
+*/
+public class SAML2LoginResponseBuilder {
+    protected static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    protected String destination;
+    protected String issuer;
+    protected int subjectExpiration;
+    protected int assertionExpiration;
+    protected String nameId;
+    protected String nameIdFormat;
+    protected boolean multiValuedRoles;
+    protected boolean disableAuthnStatement;
+    protected String requestID;
+    protected String authMethod;
+    protected String requestIssuer;
+    protected String sessionIndex;
+
+
+    public SAML2LoginResponseBuilder sessionIndex(String sessionIndex) {
+        this.sessionIndex = sessionIndex;
+        return this;
+    }
+
+    public SAML2LoginResponseBuilder destination(String destination) {
+        this.destination = destination;
+        return this;
+    }
+
+    public SAML2LoginResponseBuilder issuer(String issuer) {
+        this.issuer = issuer;
+        return this;
+    }
+
+    /**
+     * Length of time in seconds the subject can be confirmed
+     * See SAML core specification 2.4.1.2 NotOnOrAfter
+     *
+     * @param subjectExpiration Number of seconds the subject should be valid
+     * @return
+     */
+    public SAML2LoginResponseBuilder subjectExpiration(int subjectExpiration) {
+        this.subjectExpiration = subjectExpiration;
+        return this;
+    }
+
+    /**
+     * Length of time in seconds the assertion is valid for
+     * See SAML core specification 2.5.1.2 NotOnOrAfter
+     *
+     * @param assertionExpiration Number of seconds the assertion should be valid
+     * @return
+     */
+    public SAML2LoginResponseBuilder assertionExpiration(int assertionExpiration) {
+        this.assertionExpiration = assertionExpiration;
+        return this;
+    }
+
+    public SAML2LoginResponseBuilder requestID(String requestID) {
+        this.requestID =requestID;
+        return this;
+    }
+
+    public SAML2LoginResponseBuilder requestIssuer(String requestIssuer) {
+        this.requestIssuer =requestIssuer;
+        return this;
+    }
+
+    public SAML2LoginResponseBuilder authMethod(String authMethod) {
+        this.authMethod = authMethod;
+        return this;
+    }
+
+    public SAML2LoginResponseBuilder nameIdentifier(String nameIdFormat, String nameId) {
+        this.nameIdFormat = nameIdFormat;
+        this.nameId = nameId;
+        return this;
+    }
+
+    public SAML2LoginResponseBuilder multiValuedRoles(boolean multiValuedRoles) {
+        this.multiValuedRoles = multiValuedRoles;
+        return this;
+    }
+
+    public SAML2LoginResponseBuilder disableAuthnStatement(boolean disableAuthnStatement) {
+        this.disableAuthnStatement = disableAuthnStatement;
+        return this;
+    }
+
+    public Document buildDocument(ResponseType responseType) throws ConfigurationException, ProcessingException {
+        Document samlResponseDocument = null;
+
+        try {
+            SAML2Response docGen = new SAML2Response();
+            samlResponseDocument = docGen.convert(responseType);
+
+            if (logger.isTraceEnabled()) {
+                logger.trace("SAML Response Document: " + DocumentUtil.asString(samlResponseDocument));
+            }
+        } catch (Exception e) {
+            throw logger.samlAssertionMarshallError(e);
+        }
+
+        return samlResponseDocument;
+    }
+
+    public ResponseType buildModel() throws ConfigurationException, ProcessingException {
+        ResponseType responseType = null;
+
+        SAML2Response saml2Response = new SAML2Response();
+
+        // Create a response type
+        String id = IDGenerator.create("ID_");
+
+        IssuerInfoHolder issuerHolder = new IssuerInfoHolder(issuer);
+        issuerHolder.setStatusCode(JBossSAMLURIConstants.STATUS_SUCCESS.get());
+
+        IDPInfoHolder idp = new IDPInfoHolder();
+        idp.setNameIDFormatValue(nameId);
+        idp.setNameIDFormat(nameIdFormat);
+
+        SPInfoHolder sp = new SPInfoHolder();
+        sp.setResponseDestinationURI(destination);
+        sp.setRequestID(requestID);
+        sp.setIssuer(requestIssuer);
+        responseType = saml2Response.createResponseType(id, sp, idp, issuerHolder);
+
+        AssertionType assertion = responseType.getAssertions().get(0).getAssertion();
+
+        //Add request issuer as the audience restriction
+        AudienceRestrictionType audience = new AudienceRestrictionType();
+        audience.addAudience(URI.create(requestIssuer));
+        assertion.getConditions().addCondition(audience);
+
+        //Update Conditions NotOnOrAfter
+        if(assertionExpiration > 0) {
+            ConditionsType conditions = assertion.getConditions();
+            conditions.setNotOnOrAfter(XMLTimeUtil.add(conditions.getNotBefore(), assertionExpiration * 1000));
+        }
+
+        //Update SubjectConfirmationData NotOnOrAfter
+        if(subjectExpiration > 0) {
+            SubjectConfirmationDataType subjectConfirmationData = assertion.getSubject().getConfirmation().get(0).getSubjectConfirmationData();
+            subjectConfirmationData.setNotOnOrAfter(XMLTimeUtil.add(assertion.getConditions().getNotBefore(), subjectExpiration * 1000));
+        }
+
+        // Create an AuthnStatementType
+        if (!disableAuthnStatement) {
+            String authContextRef = JBossSAMLURIConstants.AC_UNSPECIFIED.get();
+            if (isNotNull(authMethod))
+                authContextRef = authMethod;
+
+            AuthnStatementType authnStatement = StatementUtil.createAuthnStatement(XMLTimeUtil.getIssueInstant(),
+                    authContextRef);
+            if (sessionIndex != null) authnStatement.setSessionIndex(sessionIndex);
+            else authnStatement.setSessionIndex(assertion.getID());
+
+            assertion.addStatement(authnStatement);
+        }
+
+        return responseType;
+    }
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/SAML2LogoutRequestBuilder.java b/saml-core/src/main/java/org/keycloak/saml/SAML2LogoutRequestBuilder.java
new file mode 100755
index 0000000..a1c7c7e
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/SAML2LogoutRequestBuilder.java
@@ -0,0 +1,87 @@
+package org.keycloak.saml;
+
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.processing.api.saml.v2.request.SAML2Request;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.protocol.LogoutRequestType;
+import org.w3c.dom.Document;
+
+import java.net.URI;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class SAML2LogoutRequestBuilder {
+    protected String userPrincipal;
+    protected String userPrincipalFormat;
+    protected String sessionIndex;
+    protected long assertionExpiration;
+    protected String destination;
+    protected String issuer;
+
+    public SAML2LogoutRequestBuilder destination(String destination) {
+        this.destination = destination;
+        return this;
+    }
+
+    public SAML2LogoutRequestBuilder issuer(String issuer) {
+        this.issuer = issuer;
+        return this;
+    }
+
+    /**
+     * Length of time in seconds the assertion is valid for
+     * See SAML core specification 2.5.1.2 NotOnOrAfter
+     *
+     * @param assertionExpiration Number of seconds the assertion should be valid
+     * @return
+     */
+    public SAML2LogoutRequestBuilder assertionExpiration(int assertionExpiration) {
+        this.assertionExpiration = assertionExpiration;
+        return this;
+    }
+
+
+    public SAML2LogoutRequestBuilder userPrincipal(String nameID, String nameIDformat) {
+        this.userPrincipal = nameID;
+        this.userPrincipalFormat = nameIDformat;
+        return this;
+    }
+
+    public SAML2LogoutRequestBuilder sessionIndex(String index) {
+        this.sessionIndex = index;
+        return this;
+    }
+
+    public Document buildDocument() throws ProcessingException, ConfigurationException, ParsingException {
+        Document document = new SAML2Request().convert(createLogoutRequest());
+        return document;
+    }
+
+    private LogoutRequestType createLogoutRequest() throws ConfigurationException {
+        LogoutRequestType lort = new SAML2Request().createLogoutRequest(issuer);
+
+        NameIDType nameID = new NameIDType();
+        nameID.setValue(userPrincipal);
+        //Deal with NameID Format
+        String nameIDFormat = userPrincipalFormat;
+        nameID.setFormat(URI.create(nameIDFormat));
+        lort.setNameID(nameID);
+
+        if (issuer != null) {
+            NameIDType issuerID = new NameIDType();
+            issuerID.setValue(issuer);
+            lort.setIssuer(issuerID);
+        }
+        if (sessionIndex != null) lort.addSessionIndex(sessionIndex);
+
+
+        if (assertionExpiration > 0) lort.setNotOnOrAfter(XMLTimeUtil.add(lort.getIssueInstant(), assertionExpiration * 1000));
+        lort.setDestination(URI.create(destination));
+        return lort;
+    }
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/SAML2LogoutResponseBuilder.java b/saml-core/src/main/java/org/keycloak/saml/SAML2LogoutResponseBuilder.java
new file mode 100755
index 0000000..6710f71
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/SAML2LogoutResponseBuilder.java
@@ -0,0 +1,75 @@
+package org.keycloak.saml;
+
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
+import org.keycloak.saml.processing.core.saml.v2.common.IDGenerator;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.protocol.StatusCodeType;
+import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+import org.keycloak.dom.saml.v2.protocol.StatusType;
+import org.w3c.dom.Document;
+
+import java.net.URI;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class SAML2LogoutResponseBuilder {
+
+    protected String logoutRequestID;
+    protected String destination;
+    protected String issuer;
+
+    public SAML2LogoutResponseBuilder logoutRequestID(String logoutRequestID) {
+        this.logoutRequestID = logoutRequestID;
+        return this;
+    }
+
+    public SAML2LogoutResponseBuilder destination(String destination) {
+        this.destination = destination;
+        return this;
+    }
+
+    public SAML2LogoutResponseBuilder issuer(String issuer) {
+        this.issuer = issuer;
+        return this;
+    }
+
+
+    public Document buildDocument() throws ProcessingException {
+        Document samlResponse = null;
+        try {
+            StatusResponseType statusResponse = new StatusResponseType(IDGenerator.create("ID_"), XMLTimeUtil.getIssueInstant());
+
+            // Status
+            StatusType statusType = new StatusType();
+            StatusCodeType statusCodeType = new StatusCodeType();
+            statusCodeType.setValue(URI.create(JBossSAMLURIConstants.STATUS_SUCCESS.get()));
+            statusType.setStatusCode(statusCodeType);
+
+            statusResponse.setStatus(statusType);
+            statusResponse.setInResponseTo(logoutRequestID);
+            NameIDType issuer = new NameIDType();
+            issuer.setValue(this.issuer);
+
+            statusResponse.setIssuer(issuer);
+            statusResponse.setDestination(destination);
+
+            SAML2Response saml2Response = new SAML2Response();
+            samlResponse = saml2Response.convert(statusResponse);
+        } catch (ConfigurationException e) {
+            throw new ProcessingException(e);
+        } catch (ParsingException e) {
+            throw new ProcessingException(e);
+        }
+        return samlResponse;
+
+    }
+
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/SAML2NameIDPolicyBuilder.java b/saml-core/src/main/java/org/keycloak/saml/SAML2NameIDPolicyBuilder.java
new file mode 100755
index 0000000..446ca36
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/SAML2NameIDPolicyBuilder.java
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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 org.keycloak.saml;
+
+import org.keycloak.dom.saml.v2.protocol.NameIDPolicyType;
+
+import java.net.URI;
+
+/**
+ * @author pedroigor
+ */
+public class SAML2NameIDPolicyBuilder {
+
+    private final NameIDPolicyType policyType;
+
+    private SAML2NameIDPolicyBuilder(String format) {
+        this.policyType = new NameIDPolicyType();
+        this.policyType.setFormat(URI.create(format));
+    }
+
+    public static SAML2NameIDPolicyBuilder format(String format) {
+        return new SAML2NameIDPolicyBuilder(format);
+    }
+
+    public NameIDPolicyType build() {
+        this.policyType.setAllowCreate(Boolean.TRUE);
+        return this.policyType;
+    }
+}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/SAMLRequestParser.java b/saml-core/src/main/java/org/keycloak/saml/SAMLRequestParser.java
new file mode 100755
index 0000000..fb4fa0a
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/SAMLRequestParser.java
@@ -0,0 +1,80 @@
+package org.keycloak.saml;
+
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.processing.api.saml.v2.request.SAML2Request;
+import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
+import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
+import org.keycloak.saml.processing.web.util.PostBindingUtil;
+import org.keycloak.saml.processing.web.util.RedirectBindingUtil;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class SAMLRequestParser {
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
+
+    public static SAMLDocumentHolder parseRequestRedirectBinding(String samlMessage) {
+        InputStream is;
+        is = RedirectBindingUtil.base64DeflateDecode(samlMessage);
+        SAML2Request saml2Request = new SAML2Request();
+        try {
+            saml2Request.getSAML2ObjectFromStream(is);
+            return saml2Request.getSamlDocumentHolder();
+        } catch (Exception e) {
+            logger.samlBase64DecodingError(e);
+        }
+        return null;
+
+    }
+
+    public static SAMLDocumentHolder parseRequestPostBinding(String samlMessage) {
+        InputStream is;
+        byte[] samlBytes = PostBindingUtil.base64Decode(samlMessage);
+        is = new ByteArrayInputStream(samlBytes);
+        SAML2Request saml2Request = new SAML2Request();
+        try {
+            saml2Request.getSAML2ObjectFromStream(is);
+            return saml2Request.getSamlDocumentHolder();
+        } catch (Exception e) {
+            logger.samlBase64DecodingError(e);
+        }
+        return null;
+    }
+
+    public static SAMLDocumentHolder parseResponsePostBinding(String samlMessage) {
+        byte[] samlBytes = PostBindingUtil.base64Decode(samlMessage);
+        return parseResponseDocument(samlBytes);
+    }
+
+    public static SAMLDocumentHolder parseResponseDocument(byte[] samlBytes) {
+        InputStream is = new ByteArrayInputStream(samlBytes);
+        SAML2Response response = new SAML2Response();
+        try {
+            response.getSAML2ObjectFromStream(is);
+            return response.getSamlDocumentHolder();
+        } catch (Exception e) {
+            logger.samlBase64DecodingError(e);
+        }
+        return null;
+    }
+
+    public static SAMLDocumentHolder parseResponseRedirectBinding(String samlMessage) {
+        InputStream is = RedirectBindingUtil.base64DeflateDecode(samlMessage);
+        SAML2Response response = new SAML2Response();
+        try {
+            response.getSAML2ObjectFromStream(is);
+            return response.getSamlDocumentHolder();
+        } catch (Exception e) {
+            logger.samlBase64DecodingError(e);
+        }
+        return null;
+
+    }
+
+
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/SignatureAlgorithm.java b/saml-core/src/main/java/org/keycloak/saml/SignatureAlgorithm.java
new file mode 100755
index 0000000..8df4bc3
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/SignatureAlgorithm.java
@@ -0,0 +1,69 @@
+package org.keycloak.saml;
+
+import java.security.Signature;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public enum SignatureAlgorithm {
+    RSA_SHA1("http://www.w3.org/2000/09/xmldsig#rsa-sha1", "http://www.w3.org/2000/09/xmldsig#sha1", "SHA1withRSA"),
+    RSA_SHA256("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "http://www.w3.org/2001/04/xmlenc#sha256", "SHA256withRSA"),
+    RSA_SHA512("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", "http://www.w3.org/2001/04/xmlenc#sha512", "SHA512withRSA"),
+    DSA_SHA1("http://www.w3.org/2000/09/xmldsig#dsa-sha1", "http://www.w3.org/2000/09/xmldsig#sha1", "SHA1withDSA")
+    ;
+    private final String xmlSignatureMethod;
+    private final String xmlSignatureDigestMethod;
+    private final String javaSignatureAlgorithm;
+
+    private static final Map<String, SignatureAlgorithm> signatureMethodMap = new HashMap<>();
+    private static final Map<String, SignatureAlgorithm> signatureDigestMethodMap = new HashMap<>();
+
+    static {
+        signatureMethodMap.put(RSA_SHA1.getXmlSignatureMethod(), RSA_SHA1);
+        signatureMethodMap.put(RSA_SHA256.getXmlSignatureMethod(), RSA_SHA256);
+        signatureMethodMap.put(RSA_SHA512.getXmlSignatureMethod(), RSA_SHA512);
+        signatureMethodMap.put(DSA_SHA1.getXmlSignatureMethod(), DSA_SHA1);
+
+        signatureDigestMethodMap.put(RSA_SHA1.getXmlSignatureDigestMethod(), RSA_SHA1);
+        signatureDigestMethodMap.put(RSA_SHA256.getXmlSignatureDigestMethod(), RSA_SHA256);
+        signatureDigestMethodMap.put(RSA_SHA512.getXmlSignatureDigestMethod(), RSA_SHA512);
+        signatureDigestMethodMap.put(DSA_SHA1.getXmlSignatureDigestMethod(), DSA_SHA1);
+    }
+
+    public static SignatureAlgorithm getFromXmlMethod(String xml) {
+        return signatureMethodMap.get(xml);
+    }
+
+    public static SignatureAlgorithm getFromXmlDigest(String xml) {
+        return signatureDigestMethodMap.get(xml);
+    }
+
+    SignatureAlgorithm(String xmlSignatureMethod, String xmlSignatureDigestMethod, String javaSignatureAlgorithm) {
+        this.xmlSignatureMethod = xmlSignatureMethod;
+        this.xmlSignatureDigestMethod = xmlSignatureDigestMethod;
+        this.javaSignatureAlgorithm = javaSignatureAlgorithm;
+    }
+
+    public String getXmlSignatureMethod() {
+        return xmlSignatureMethod;
+    }
+
+    public String getXmlSignatureDigestMethod() {
+        return xmlSignatureDigestMethod;
+    }
+
+    public String getJavaSignatureAlgorithm() {
+        return javaSignatureAlgorithm;
+    }
+
+    public Signature createSignature() {
+        try {
+            return Signature.getInstance(javaSignatureAlgorithm);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/saml-core/src/main/java/org/keycloak/saml/SPMetadataDescriptor.java b/saml-core/src/main/java/org/keycloak/saml/SPMetadataDescriptor.java
new file mode 100755
index 0000000..78ff2f3
--- /dev/null
+++ b/saml-core/src/main/java/org/keycloak/saml/SPMetadataDescriptor.java
@@ -0,0 +1,35 @@
+package org.keycloak.saml;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class SPMetadataDescriptor {
+    public static String getSPDescriptor(String binding, String assertionEndpoint, String logoutEndpoint, boolean wantAuthnRequestsSigned, String entityId, String nameIDPolicyFormat, String certificatePem) {
+        String descriptor =
+                "<EntityDescriptor xmlns=\"urn:oasis:names:tc:SAML:2.0:metadata\" entityID=\"" + entityId + "\">\n" +
+                "    <SPSSODescriptor AuthnRequestsSigned=\"" + wantAuthnRequestsSigned + "\"\n" +
+                "            protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol http://schemas.xmlsoap.org/ws/2003/07/secext\">\n" +
+                "        <NameIDFormat>" + nameIDPolicyFormat + "\n" +
+                "        </NameIDFormat>\n" +
+                "        <SingleLogoutService Binding=\"" + binding + "\" Location=\"" + logoutEndpoint + "\"/>\n" +
+                "        <AssertionConsumerService\n" +
+                "                Binding=\"" + binding + "\" Location=\"" + assertionEndpoint + "\"\n" +
+                "                index=\"1\" isDefault=\"true\" />\n";
+        if (wantAuthnRequestsSigned) {
+            descriptor +=
+                "        <KeyDescriptor use=\"signing\">\n" +
+                "            <dsig:KeyInfo xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\">\n" +
+                "                <dsig:X509Data>\n" +
+                "                    <dsig:X509Certificate>\n" + certificatePem + "\n" +
+                "                    </dsig:X509Certificate>\n" +
+                "                </dsig:X509Data>\n" +
+                "            </dsig:KeyInfo>\n" +
+                "        </KeyDescriptor>\n";
+        }
+        descriptor +=
+                "    </SPSSODescriptor>\n" +
+                "</EntityDescriptor>\n";
+        return descriptor;
+    }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java
index eb25ff0..308fb67 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java
@@ -155,12 +155,16 @@ public class KeycloakServer {
             }
 
             File dir = new File(resources).getAbsoluteFile();
-            if (!dir.isDirectory() || !new File(dir, "forms").isDirectory()) {
-                throw new RuntimeException("Invalid resources directory");
+            if (!dir.isDirectory()) {
+                throw new RuntimeException("Invalid base resources directory");
+
+            }
+            if (!new File(dir, "themes").isDirectory()) {
+                throw new RuntimeException("Invalid resources forms directory");
             }
 
             if (!System.getProperties().containsKey("keycloak.theme.dir")) {
-                System.setProperty("keycloak.theme.dir", file(dir.getAbsolutePath(), "forms", "common-themes", "src", "main", "resources", "theme").getAbsolutePath());
+                System.setProperty("keycloak.theme.dir", file(dir.getAbsolutePath(), "themes", "src", "main", "resources", "theme").getAbsolutePath());
             } else {
                 String foo = System.getProperty("keycloak.theme.dir");
                 System.out.println(foo);